一、权限示例

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

  • 普通用户:只能查看个人信息相关,序号: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. codeforces 54A

    题意:收到礼物的规则为每个假日必收到一份礼物,每K天里至少收到一份礼物,求出N天中收到的礼物的最小数量. 思路:将N天根据假日所在天数分为一段段,当假日与假日之间间隔天数hol[i]>-hol[ ...

  2. Nginx初步配置

    编辑 简介 Nginx ("engine x") 是一个轻量级,高性能的HTTP和反向代理服务器,也是一个IMAP/POP3/SMTP服务器.Nginx是由Igor Sysoev为 ...

  3. java深入探究06

    Tomcat中获取资源文件: ServletContext().getRealPath(/WEB-INF/classes/db.properties);//获取资源文件的在服务器中的绝对路径 Serv ...

  4. Linux课程---6、别名管理和网络配置(Linux命令如何记)

    Linux课程---6.别名管理和网络配置(Linux命令如何记) 一.总结 一句话总结: 理解记忆:因为命令要实现那么多功能,必须有那么多参数,而不同的参数就适用不用的情况 命令基本格式:命令关键字 ...

  5. 目标检测 — Inception-ResNet-v2

    这篇文章介绍的网络有Inception V1.Inception V2.Inception V3.Inception V4与Inception-ResNet-V2. 1.Inception V1 主要 ...

  6. 关于解决SSHD 连接 认证失败的问题

    网上找有很多方法,有时候情况不一样 ,也不实用 其实找到解决问题的思路更总要 首先分析日志文件 less /var/log/secure | grep sshd ,看具体出现什么问题 然后再去搜索相关 ...

  7. xdebug浏览器调试参数

    XDEBUG_SESSION_START=phpstorm-xdebug 找到对应PHP版本的 Xdebug ,后面带 TS 的为线程安全,本机环境为 win7 64 + php-5.5.1-Win3 ...

  8. L2-016 愿天下有情人都是失散多年的兄妹(25 分)

    呵呵.大家都知道五服以内不得通婚,即两个人最近的共同祖先如果在五代以内(即本人.父母.祖父母.曾祖父母.高祖父母)则不可通婚.本题就请你帮助一对有情人判断一下,他们究竟是否可以成婚? 输入格式: 输入 ...

  9. jexus入门

    参考:https://www.linuxdot.net/bbsfile-3084 一.Jexus简介:Jexus web server for linux 是一款基于.NET兼容环境,运行于Linux ...

  10. 排序----demo----

    排序1---冒泡法: 单向冒泡排序的基本原理就是:对于给定的n个数据,从第一个数据开始一次对相邻的两个数据进行比较,当前面的数据大于后面的数据时,交换位置,进行一轮比较和换位后,n个数据中最大的那个被 ...