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 - 文 ...
随机推荐
- codeforces 54A
题意:收到礼物的规则为每个假日必收到一份礼物,每K天里至少收到一份礼物,求出N天中收到的礼物的最小数量. 思路:将N天根据假日所在天数分为一段段,当假日与假日之间间隔天数hol[i]>-hol[ ...
- Nginx初步配置
编辑 简介 Nginx ("engine x") 是一个轻量级,高性能的HTTP和反向代理服务器,也是一个IMAP/POP3/SMTP服务器.Nginx是由Igor Sysoev为 ...
- java深入探究06
Tomcat中获取资源文件: ServletContext().getRealPath(/WEB-INF/classes/db.properties);//获取资源文件的在服务器中的绝对路径 Serv ...
- Linux课程---6、别名管理和网络配置(Linux命令如何记)
Linux课程---6.别名管理和网络配置(Linux命令如何记) 一.总结 一句话总结: 理解记忆:因为命令要实现那么多功能,必须有那么多参数,而不同的参数就适用不用的情况 命令基本格式:命令关键字 ...
- 目标检测 — Inception-ResNet-v2
这篇文章介绍的网络有Inception V1.Inception V2.Inception V3.Inception V4与Inception-ResNet-V2. 1.Inception V1 主要 ...
- 关于解决SSHD 连接 认证失败的问题
网上找有很多方法,有时候情况不一样 ,也不实用 其实找到解决问题的思路更总要 首先分析日志文件 less /var/log/secure | grep sshd ,看具体出现什么问题 然后再去搜索相关 ...
- xdebug浏览器调试参数
XDEBUG_SESSION_START=phpstorm-xdebug 找到对应PHP版本的 Xdebug ,后面带 TS 的为线程安全,本机环境为 win7 64 + php-5.5.1-Win3 ...
- L2-016 愿天下有情人都是失散多年的兄妹(25 分)
呵呵.大家都知道五服以内不得通婚,即两个人最近的共同祖先如果在五代以内(即本人.父母.祖父母.曾祖父母.高祖父母)则不可通婚.本题就请你帮助一对有情人判断一下,他们究竟是否可以成婚? 输入格式: 输入 ...
- jexus入门
参考:https://www.linuxdot.net/bbsfile-3084 一.Jexus简介:Jexus web server for linux 是一款基于.NET兼容环境,运行于Linux ...
- 排序----demo----
排序1---冒泡法: 单向冒泡排序的基本原理就是:对于给定的n个数据,从第一个数据开始一次对相邻的两个数据进行比较,当前面的数据大于后面的数据时,交换位置,进行一轮比较和换位后,n个数据中最大的那个被 ...