rest framework 权限
一、权限示例
需求:不同的用户类型有不同的权限
- 普通用户:只能查看个人信息相关,序号:1
- VIP 用户:只能查看个人信息相关,序号:2
- SVIP 用户:查看订单相关信息,序号:3
1、新建 app/utils/permission.py
:
class SVIPPermission(object):
def has_permission(self, request, view):
"""是否有权限"""
if request.user.user_type != 3:
return False
return True
class MyPermission(object):
"""普通、VIP 用户"""
def has_permission(self, request, view):
"""是否有权限"""
if request.user.user_type == 3:
return False
return True
如果用户类型为 3 即 SVIP,那么就返回 True,否则返回 False。
Note:只有登录后的用户才有
request.user
,即在用户认证的时候,返回用户对象
2、views.py
from django.shortcuts import render, HttpResponse
from rest_framework.views import APIView
from rest_framework.authentication import BasicAuthentication
import hashlib
import time
from app import models
from django.http import JsonResponse
from .utils.auth import MyAuthentication
from .utils.permission import SVIPPermission
class OrderView(APIView):
"""订单管理"""
# authentication_classes = [MyAuthentication, ] # 添加认证(因为已经全局设置了认证,所有就不单独设置了)
permission_classes = [SVIPPermission, ] # 权限
def get(self, request, *args, **kwargs):
ret = {'code': 1000, 'msg': None, 'data': None, }
ret['data'] = ORDER_DICT
print(request.user)
return JsonResponse(ret)
class UserInfo(APIView):
"""用户个人信息"""
permission_classes = [MyPermission, ]
def get(self, request, *args, **kwargs):
user_name = request.user.username
return HttpResponse(user_name)
3、现在带上 token(表示已经登录),查看订单:
SVIP 用户:
4、查看用户个人信息:(rose:普通用户)
5、project/urls.py
:
为了遵循 RESTful API 规范,现在将 URL 修改为如下:
from django.contrib import admin
from django.urls import path
from app.views import IndexView, OrderView, UserInfo
urlpatterns = [
path('admin/', admin.site.urls),
path('api/v1/index/', IndexView.as_view()),
path('api/v1/order/', OrderView.as_view()),
path('api/v1/info/', UserInfo.as_view())
]
二、全局配置
与认证一样,权限也可以全局配置和局部配置,全局配置可以使得所有的视图类生效,需要在 settings
中配置:
REST_FRAMEWORK = {
"DEFAULT_AUTHENTICATION_CLASSES": ['app.utils.auth.MyAuthentication', ],
"UNAUTHENTICATED_USER": lambda: '匿名用户',
"UNAUTHENTICATED_TOKEN": None,
"DEFAULT_PERMISSION_CLASSES": ['app.utils.permission.SVIPPermission'], # 这句
}
如果想配置没有访问权限返回的信息,可以修改 app/utils/permission.py
:
class SVIPPermission(object):
message = '必须 SVIP 才能访问!' # 这句
def has_permission(self, request, view):
"""是否有权限"""
if request.user.user_type != 3:
return False
return True
三、内置权限
rest framework 也有内置的权限 rest_framework/permissions.py
:
@six.add_metaclass(BasePermissionMetaclass)
class BasePermission(object):
"""
A base class from which all permission classes should inherit.
"""
def has_permission(self, request, view):
"""
Return `True` if permission is granted, `False` otherwise.
"""
return True
def has_object_permission(self, request, view, obj):
"""
Return `True` if permission is granted, `False` otherwise.
"""
return True
自定义的权限类,最好要继承 BasePermission
:
# app/utils/permisiion.py
from rest_framework.permissions import BasePermission
class SVIPPermission(BasePermission):
message = '必须 SVIP 才能访问!'
def has_permission(self, request, view):
"""是否有权限"""
if request.user.user_type != 3:
return False
return True
四、权限认证流程(源码)
1、请求过来先执行 dispatch()
方法,dispatch()
方法中 initial()
初始化请求相关信息:
def initial(self, request, *args, **kwargs):
"""
Runs anything that needs to occur prior to calling the method handler.
"""
self.format_kwarg = self.get_format_suffix(**kwargs)
# Perform content negotiation and store the accepted info on the request
neg = self.perform_content_negotiation(request)
request.accepted_renderer, request.accepted_media_type = neg
# Determine the API version, if versioning is in use.
version, scheme = self.determine_version(request, *args, **kwargs)
request.version, request.versioning_scheme = version, scheme
# Ensure that the incoming request is permitted
# 实现认证
self.perform_authentication(request)
# 检查权限
self.check_permissions(request)
self.check_throttles(request)
2、check_permissions()
def check_permissions(self, request):
"""
Check if the request should be permitted.
Raises an appropriate exception if the request is not permitted.(检查是否应该允许请求。
如果不允许请求,则引发适当的异常)
"""
# 权限列表,self.get_permissions() = MyPermission(),调用其中的 has_permission() 方法
for permission in self.get_permissions():
if not permission.has_permission(request, self):
self.permission_denied(
request, message=getattr(permission, 'message', None)
)
从上面可以看到其实权限认证,主要是调用 has_permission()
方法,若我们自定义权限类,只需实现这个方法即可。
self.get_permissions()
其本质是在定义权限类对象列表:[MyPermission(), ]
,具体可见 3
- 若
has_permission()
返回 True,即有权限访问,则不执行self.permission_denied()
- 若访问 False,即无权访问,则执行
self.permission_denied()
,在其中返回的错误信息就是message
所定义的,因此我们也可以自定义message
的内容。
3、get_permissions()
def get_permissions(self):
"""
Instantiates and returns the list of permissions that this view requires.
实例化并返回此视图所需的权限列表。
"""
# permission_classes = [MyPermission, ],返回对象列表
return [permission() for permission in self.permission_classes]
源码流程图
总结
- 自定权限类,需继承
BasePermission
- 类中必须实现
has_permission()
方法 - 全局定义权限(可设置 settings),局部视图类不设置权限认证,可设置
permission_classes = []
rest framework 权限的更多相关文章
- Django REST framework - 权限和限制
目录 Django REST framework 权限和限制 (你能干什么) 设置权限的方法 案例 第一步: 定义一个权限类 第二步: 使用 视图级别 全局级别设置 --- 限制 (你一分钟能干多少次 ...
- Django rest framework ---- 权限
Django rest framework ---- 权限 添加权限 api/utils文件夹下新建premission.py文件,代码如下: message是当没有权限时,提示的信息 # FileN ...
- django rest framework权限和认证
Django rest framework之权限 一.Authentication用户认证配置 1.四种验证及官网描述: BasicAuthentication 此身份验证方案使用HTTP基本身份验证 ...
- Django rest framework 权限操作(源码分析)
知识回顾http://www.cnblogs.com/ctztake/p/8419059.html 这一篇是基于上一篇写的,上一篇谢了认证的具体流程,看懂了上一篇这一篇才能看懂, 当用户访问是 首先执 ...
- Django REST framework —— 权限组件源码分析
在上一篇文章中我们已经分析了认证组件源码,我们再来看看权限组件的源码,权限组件相对容易,因为只需要返回True 和False即可 代码 class ShoppingCarView(ViewSetMix ...
- django的rest framework框架——认证、权限、节流控制
一.登录认证示例 模拟用户登录,获取token,当用户访问订单或用户中心时,判断用户携带正确的token,则允许查看订单和用户信息,否则抛出异常: from django.conf.urls impo ...
- DRF 权限和频率
Django Rest Framework 权限组件 DRF的权限 权限组件源码解析 我们之前说过了DRF的版本和认证~也知道了权限和频率跟版本认证都是在initial方法里初始化的~~ 其实我们版本 ...
- python测试开发django-rest-framework-61.权限认证(permission)
前言 用户登录后,才有操作当前用户的权限,不能操作其它人的用户,这就是需要用到权限认证,要不然你登录自己的用户,去操作别人用户的相关数据,就很危险了. authentication是身份认证,判断当前 ...
- python 全栈之路
目录 Python 全栈之路 一. Python 1. Python基础知识部分 2. Python -函数 3. Python - 模块 4. Python - 面对对象 5. Python - 文 ...
随机推荐
- sql的执行过程
from ===> where ===> group by ===> select ===>order by 这个执行流程 很重要~~
- 解决css的float父div没有高度
在做页面设计常会碰到css的float父div没有高度的情况,HTML代码设计 <div class='box'> <div class='float_left'></d ...
- LINQ 学习路程 -- 查询语法 LINQ Query Syntax
1.查询语法 Query Syntax: from <range variable> in <IEnumerable<T> or IQueryable<T> ...
- 【转】HTTP方法
[转]HTTP方法 掌握HTTP虽然不是必须的,但是如果你知道它的工作原理,那么在学习JSP开发中的某些知识就可以易如反掌了. 一,HTTP协议详解之URL篇 http(超文本传输协议)是一个基于请求 ...
- Drools Fusion (CEP) Example 和 关键概念
Drools Fusion (Complex Event Processing) 是Drools对于复杂事件处理的模块, 与它功能相似的是Esper, 两者都可以提供基于时间跨度和滑动窗口的事件处理, ...
- python第三篇:python、flask关系映射
python中关系映射主要包括三种:一对多关系映射.一对一关系映射.多对多关系映射. 一对多关系映射 一方:Student(学生) 添加关联属性和反向引用 多方:Article(文章) 添加外键关联 ...
- PLSQL Developer使用技巧整理
Shortcut: =============================================================================== Edit/Und ...
- python glances来监控linux服务器CPU 内存 IO使用
什么是 Glances? Glances 是一个由 Python 编写,使用 psutil 库来从系统抓取信息的基于 curses 开发的跨平台命令行系统监视工具. 通过 Glances,我们可以监视 ...
- pyget-资源与标签(Sprite、Label、Font)
Sprite精灵,是游戏中对具有动画作用功能的图片的爱称. 精灵,图标和字体等资源是不能够处理事件的,因为它们并不是继承自EventDispatcher.但是可以包含一个能够EventDispatch ...
- C语言小程序(三)、判断两个日期之差
输入两个日期,计算之间相差多少天. 用了两种方法实现,第二种利用结构体,代码比较清晰,其余的都一样. 1.普通的写法 #include <stdio.h> int leapyear(int ...