一、权限示例

需求:不同的用户类型有不同的权限

  • 普通用户:只能查看个人信息相关,序号: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 权限的更多相关文章

  1. Django REST framework - 权限和限制

    目录 Django REST framework 权限和限制 (你能干什么) 设置权限的方法 案例 第一步: 定义一个权限类 第二步: 使用 视图级别 全局级别设置 --- 限制 (你一分钟能干多少次 ...

  2. Django rest framework ---- 权限

    Django rest framework ---- 权限 添加权限 api/utils文件夹下新建premission.py文件,代码如下: message是当没有权限时,提示的信息 # FileN ...

  3. django rest framework权限和认证

    Django rest framework之权限 一.Authentication用户认证配置 1.四种验证及官网描述: BasicAuthentication 此身份验证方案使用HTTP基本身份验证 ...

  4. Django rest framework 权限操作(源码分析)

    知识回顾http://www.cnblogs.com/ctztake/p/8419059.html 这一篇是基于上一篇写的,上一篇谢了认证的具体流程,看懂了上一篇这一篇才能看懂, 当用户访问是 首先执 ...

  5. Django REST framework —— 权限组件源码分析

    在上一篇文章中我们已经分析了认证组件源码,我们再来看看权限组件的源码,权限组件相对容易,因为只需要返回True 和False即可 代码 class ShoppingCarView(ViewSetMix ...

  6. django的rest framework框架——认证、权限、节流控制

    一.登录认证示例 模拟用户登录,获取token,当用户访问订单或用户中心时,判断用户携带正确的token,则允许查看订单和用户信息,否则抛出异常: from django.conf.urls impo ...

  7. DRF 权限和频率

    Django Rest Framework 权限组件 DRF的权限 权限组件源码解析 我们之前说过了DRF的版本和认证~也知道了权限和频率跟版本认证都是在initial方法里初始化的~~ 其实我们版本 ...

  8. python测试开发django-rest-framework-61.权限认证(permission)

    前言 用户登录后,才有操作当前用户的权限,不能操作其它人的用户,这就是需要用到权限认证,要不然你登录自己的用户,去操作别人用户的相关数据,就很危险了. authentication是身份认证,判断当前 ...

  9. python 全栈之路

    目录 Python 全栈之路 一. Python 1. Python基础知识部分 2. Python -函数 3. Python - 模块 4. Python - 面对对象 5. Python - 文 ...

随机推荐

  1. sql的执行过程

    from ===> where ===> group by ===> select ===>order by 这个执行流程 很重要~~

  2. 解决css的float父div没有高度

    在做页面设计常会碰到css的float父div没有高度的情况,HTML代码设计 <div class='box'> <div class='float_left'></d ...

  3. LINQ 学习路程 -- 查询语法 LINQ Query Syntax

    1.查询语法 Query Syntax: from <range variable> in <IEnumerable<T> or IQueryable<T> ...

  4. 【转】HTTP方法

    [转]HTTP方法 掌握HTTP虽然不是必须的,但是如果你知道它的工作原理,那么在学习JSP开发中的某些知识就可以易如反掌了. 一,HTTP协议详解之URL篇 http(超文本传输协议)是一个基于请求 ...

  5. Drools Fusion (CEP) Example 和 关键概念

    Drools Fusion (Complex Event Processing) 是Drools对于复杂事件处理的模块, 与它功能相似的是Esper, 两者都可以提供基于时间跨度和滑动窗口的事件处理, ...

  6. python第三篇:python、flask关系映射

    python中关系映射主要包括三种:一对多关系映射.一对一关系映射.多对多关系映射. 一对多关系映射 一方:Student(学生) 添加关联属性和反向引用 多方:Article(文章) 添加外键关联 ...

  7. PLSQL Developer使用技巧整理

      Shortcut: =============================================================================== Edit/Und ...

  8. python glances来监控linux服务器CPU 内存 IO使用

    什么是 Glances? Glances 是一个由 Python 编写,使用 psutil 库来从系统抓取信息的基于 curses 开发的跨平台命令行系统监视工具. 通过 Glances,我们可以监视 ...

  9. pyget-资源与标签(Sprite、Label、Font)

    Sprite精灵,是游戏中对具有动画作用功能的图片的爱称. 精灵,图标和字体等资源是不能够处理事件的,因为它们并不是继承自EventDispatcher.但是可以包含一个能够EventDispatch ...

  10. C语言小程序(三)、判断两个日期之差

    输入两个日期,计算之间相差多少天. 用了两种方法实现,第二种利用结构体,代码比较清晰,其余的都一样. 1.普通的写法 #include <stdio.h> int leapyear(int ...