一、权限实例
在阅读本文之前请先参考django rest framework 之 认证 中关于 django rest framework
的相关内容及实例
1、目录结构
为了更好的管理各个功能组件,在django rest framework 之 认证 中我们说到可以将认证类单独的拿出来,放到其他目录下,然后导入到 views.py
文件中,在权限环节我们亦可以这么做,目录结构就变成这样
在api这个app下创建一个utils包专门用来存放相关的组件。
2、为模型类添加认证字段
我们在models.py中定义了两个模型类,分别是
from django.db import models class UserInfo(models.Model): USER_TYPE = ( (1,'普通用户'), (2,'VIP'), (3,'SVIP') ) user_type = models.IntegerField(choices=USER_TYPE, default=1) username = models.CharField(max_length=32) password = models.CharField(max_length=64) class UserToken(models.Model): user = models.OneToOneField(UserInfo,on_delete=models.CASCADE) token = models.CharField(max_length=64)
在 UserInfo
中通过为用户添加一个 user_type
字段来保证用户的身份,是普通用户,VIP还是SVIP,这样就可以通过用户的身份验证不同的权限。如果想要定义一个视图类,这个类中的逻辑只有超级用户才能访问。
3、具体权限认证
可以再utils中的 permissions.py
中这么写
# utils/permission.py class SVIPPremission(object): message = "必须是SVIP才能访问" # 这里的message表示如果不通过权限的时候,错误提示信息 def has_permission(self,request,view): if request.user.user_type != 3: return False return True class MyPremission(object): # 这个权限类表示当用户为SVIP时不可通过 def has_permission(self,request,view): if request.user.user_type == 3: return False return True
这里只是判断用户的 USER_TYPE
的字段,判断用户是否有权限,也可以添加其他的逻辑进行判断。
4、全局配置
在上一节的django rest framework 之 认证 的认证中,将认证类放到了 settings.py
文件中,这样会作用到视图中的每一个视图类,如果视图类想要自己进行认证,只需要重写 authentication_classes
即可,那么对于权限来说我们也可以这么做,
REST_FRAMEWORK = { 'DEFAULT_AUTHENTICATION_CLASSES': ['api.utils.authenticate.FirstAuthenticate', 'api.utils.authenticate.MyAuthenticate'], "UNAUTHENTICATED_USER": None, # 匿名,request.user = None "UNAUTHENTICATED_TOKEN": None,# 匿名,request.auth = None "DEFAULT_PERMISSION_CLASSES": ['api.utils.permission.MyPermission'], # 表示每一个视图类(只要不重写permission_classes属性),都需要SVIP的用户才能访问。 }
5、视图
在视图 view.py
中定义一个用户详情类 UserInfoView
作为测试,这里的视图和上一节的django rest framework 之 认证 是相接的。
from django.shortcuts import render, HttpResponse from django.http import JsonResponse from django.views import View from rest_framework.views import APIView from rest_framework.request import Request from .utils import authenticate, permission from api import models import json def md5(user): import hashlib import time # 当前时间,相当于生成一个随机的字符串 ctime = str(time.time()) # token加密 m = hashlib.md5(bytes(user, encoding='utf-8')) m.update(bytes(ctime, encoding='utf-8')) return m.hexdigest() class AuthView(APIView): '''用于用户登录验证''' authentication_classes = [] #里面为空,代表不需要认证 permission_classes = [] #不里面为空,代表不需要权限 def get(self, request, *args, **kwargs): ret = {'code': 1000, 'msg': 'success', 'name': '偷偷'} ret = json.dumps(ret, ensure_ascii=False) return HttpResponse(ret) def post(self,request,*args,**kwargs): ret = {'code':1000,'msg':None} try: user = request.POST.get('username') pwd = request.POST.get('password') print(user, pwd) obj = models.UserInfo.objects.filter(username=user,password=pwd).first() print(obj.username, obj.password) if not obj: ret['code'] = 1001 ret['msg'] = '用户名或密码错误' #为用户创建token token = md5(user) #存在就更新,不存在就创建 models.UserToken.objects.update_or_create(user=obj,defaults={'token':token}) ret['token'] = token except Exception as e: ret['code'] = 1002 ret['msg'] = '请求异常' return JsonResponse(ret) ORDER_DICT = { 1:{ 'name':'apple', 'price':15 }, 2:{ 'name':'狗子', 'price':100 } } class OrderView(APIView): # 用户想要获取订单,就要先通过身份认证、在全局settings.py 中已经配置 permission_classes = [] def get(self, request, *args, **kwargs): ret = { 'code': 1024, 'msg': '订单获取成功', } try: ret['data'] = ORDER_DICT except Exception as e: pass return JsonResponse(ret) class UserInfoView(APIView): permission_classes = [permission.SVIPPermission] def get(self, request, *args, **kwargs): print(request.user) return HttpResponse('SVIP用户信息')
这里的 UserInfoView
重写了 permission_classes
属性,则不会再使用 settings.py
中关于认证类的配置。表示只有SVIP才能访问这个类的内部。
6、路由分发
在url.py中设置路由分发
from django.conf.urls import url from api.views import AuthView, OrderView, UserInfoView urlpatterns = [ url(r'^api/v1/auth/$', AuthView.as_view()), url(r'^api/v1/order/$', OrderView.as_view()), url(r'^api/v1/info/$', UserInfoView.as_view()), ]
7、请求测试
Postman或者浏览器发送请求,由于我们在 setting.py
中配置了 'DEFAULT_AUTHENTICATION_CLASSES': ['api.utils.authenticate.FirstAuthenticate', 'api.utils.authenticate.MyAuthenticate'],
会对请求进行认证,所以要带这用户的 token
才能通过,进入到权限组件。
进入sqlite数据库,找到对应的注册用户
在数据库中,拿到刷新的用户的最近一次的token
拿到这个token发送请求
请求成功,则说明权限生效,也可以在将 UserInfoView
改成如下
class UserInfoView(APIView): permission_classes = [permission.SVIPPermission] def get(self, request, *args, **kwargs): print(request.user) return HttpResponse('SVIP用户信息')
在发送请求,就会发现用户不会有权限的提示信息。如下
二、源码分析
像 django rest framework 之 认证 一样进入, request
的请求流程,进入源码查看具体权限的操作
1、进入dispath()方法
2、进入initial()方法
3、进入check_permissions()方法
4、权限类的具体操作
在这里可以看到和认证中有类似的操作,获取所有的权限类,并且执行每一个权限类的 has_permission()
方法,而这个方法具体封装了我们的判断权限操作,但是 has_permission()
方法的返回值需要时 False
或者 True
, self.permission_denied(request, message=getattr(permission, 'message', None))
说明可以在权限类中重写 message
属性,来定义权限不通过时候的提示信息。
进入 self.get_permissions()
来看一下
4、获取所有的权限类
在APIView中有定义默认的权限类,因此也可以通过全局配置的方法配置权限类。
5、原生的权限类
像认证那样, django rest framework
中也有权限类
可以根据自己的需要调用。
三、总结
权限其实的流程跟之前的认证流程是一样的,认证类封装到 request
中,然后再调用认证类的方法,不过这里的方法返回值不再是像认证组件那样的直接返回一个认证的对象,而是返回一个 True
或者 False
值表示认证过的对象是否有某些权限再进行具体操作。
这里注意的是,在自己重写权限类的相关方法,添加自己的逻辑的时候,返回值需要是一个布尔值, Flase
或者 True
,表示是否有权限。也可以通过全局配置和局部配置权限类。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。
免责声明:本站资源来自互联网收集,仅供用于学习和交流,请遵循相关法律法规,本站一切资源不代表本站立场,如有侵权、后门、不妥请联系本站删除!
稳了!魔兽国服回归的3条重磅消息!官宣时间再确认!
昨天有一位朋友在大神群里分享,自己亚服账号被封号之后居然弹出了国服的封号信息对话框。
这里面让他访问的是一个国服的战网网址,com.cn和后面的zh都非常明白地表明这就是国服战网。
而他在复制这个网址并且进行登录之后,确实是网易的网址,也就是我们熟悉的停服之后国服发布的暴雪游戏产品运营到期开放退款的说明。这是一件比较奇怪的事情,因为以前都没有出现这样的情况,现在突然提示跳转到国服战网的网址,是不是说明了简体中文客户端已经开始进行更新了呢?
更新日志
- 凤飞飞《我们的主题曲》飞跃制作[正版原抓WAV+CUE]
- 刘嘉亮《亮情歌2》[WAV+CUE][1G]
- 红馆40·谭咏麟《歌者恋歌浓情30年演唱会》3CD[低速原抓WAV+CUE][1.8G]
- 刘纬武《睡眠宝宝竖琴童谣 吉卜力工作室 白噪音安抚》[320K/MP3][193.25MB]
- 【轻音乐】曼托凡尼乐团《精选辑》2CD.1998[FLAC+CUE整轨]
- 邝美云《心中有爱》1989年香港DMIJP版1MTO东芝首版[WAV+CUE]
- 群星《情叹-发烧女声DSD》天籁女声发烧碟[WAV+CUE]
- 刘纬武《睡眠宝宝竖琴童谣 吉卜力工作室 白噪音安抚》[FLAC/分轨][748.03MB]
- 理想混蛋《Origin Sessions》[320K/MP3][37.47MB]
- 公馆青少年《我其实一点都不酷》[320K/MP3][78.78MB]
- 群星《情叹-发烧男声DSD》最值得珍藏的完美男声[WAV+CUE]
- 群星《国韵飘香·贵妃醉酒HQCD黑胶王》2CD[WAV]
- 卫兰《DAUGHTER》【低速原抓WAV+CUE】
- 公馆青少年《我其实一点都不酷》[FLAC/分轨][398.22MB]
- ZWEI《迟暮的花 (Explicit)》[320K/MP3][57.16MB]