一 添加权限

(1)API/utils文件夹下新建premission.py文件,代码如下:

  • message是当没有权限时,提示的信息
#!/usr/bin/env python
# coding:utf-8 from rest_framework.permissions import BasePermission class SVIPPermission(BasePermission):
message = "必须是SVIP才能访问,你权限太低,滚"
def has_permission(self,request,view):
# request.user 表示获取到 UserInfo 这个类的对象
if request.user.user_type != 3:
return False
return True class MyPermission(BasePermission):
message = "没有权限查看我,滚"
def has_permission(self,request,view):
if request.user.user_type == 3:
return False
return True

  

(2)settings.py全局配置权限

REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': ['API.utils.auth.Authentication',],
'DEFAULT_PERMISSION_CLASSES': ['API.utils.permission.SVIPPermission'],
}

  

(3)views.py添加权限

  • 默认所有的业务都需要SVIP权限才能访问
  • OrderView类里面没写表示使用全局配置的SVIPPremission
  • UserInfoView类,因为是普通用户和VIP用户可以访问,不使用全局的,要想局部使用的话,里面就写上自己的权限类
  • permission_classes = [MyPremission,]   #局部使用权限方法
#!/usr/bin/env python
# coding:utf-8
from django.shortcuts import render,HttpResponse from django.http import JsonResponse
from rest_framework.views import APIView
from API import models
from rest_framework.request import Request
from rest_framework import exceptions
from rest_framework.authentication import BasicAuthentication
from API.utils.permission import SVIPPermission,MyPermission import hashlib
import time
def md5(user):
ctime = str(time.time())
m = hashlib.md5(user)
m.update(ctime)
return m.hexdigest() class AuthView(APIView):
authentication_classes = []
permission_classes = []
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('=============%s' %(obj))
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'] = '请求异常' # user = request._request.POST.get('username')
# pwd = request._request.POST.get('password')
# print(user,pwd)
# obj = models.UserInfo.objects.filter(username=user,password=pwd).first()
# print('=============%s' %(obj))
# 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
return JsonResponse(ret) ORDER_DICT = {
1: {
'name': 'apple',
'price': 15,
},
2: {
'name': 'dog',
'price': 100
}
}
# class Authentication(APIView):
# """
# 认证类
# """
# def authenticate(self,request):
# token = request._request.GET.get('token')
# token_obj = models.UserToken.objects.filter(token=token).first()
# if not token_obj:
# raise exceptions.AuthenticationFailed('用户认证失败')
# # 在rest framework内部会将这2个字段赋值给request,以供后续使用
# return (token_obj.user,token_obj)
#
# def authenticate_header(self,reqeust):
# pass class OrderView(APIView):
"""订单相关业务"""
# authentication_classes = [] # 添加认证
def get(self,request,*args,**kwargs):
print(request.user)
print(request.auth)
# print(request.__dict__)
ret = {'code':1000,'msg':None, 'data': None}
try:
ret['data'] = ORDER_DICT
except Exception as e:
pass
return JsonResponse(ret) class UserInfoView(APIView):
permission_classes = [MyPermission]
def get(self,request,*args,**kwargs):
print(request.user)
return HttpResponse('用户信息')

  

urls.py

from django.conf.urls import url
from django.contrib import admin
from API import views
urlpatterns = [
# url(r'^admin/', admin.site.urls),
url(r'api/v1/auth', views.AuthView.as_view()),
url(r'api/v1/order', views.OrderView.as_view()),
url(r'api/v1/info', views.UserInfoView.as_view()),
]

  

API/utils/auth.py

#!/usr/bin/env python
# coding:utf-8 from rest_framework import exceptions
from API import models
from rest_framework.authentication import BasicAuthentication class Authentication(BasicAuthentication):
def authenticate(self,request):
token = request._request.GET.get('token')
token_obj = models.UserToken.objects.filter(token=token).first()
if not token_obj:
raise exceptions.AuthenticationFailed('认证失败')
return (token_obj.user, token_obj) def authenticate_header(self, request):
pass

  

(4)测试

先get我的token

先来看看有哪些人

看一下权限逻辑,确实如果user_type == 3的话,就是没权限,并且message 中定义了,让我滚了。

#!/usr/bin/env python
# coding:utf-8 from rest_framework.permissions import BasePermission class SVIPPermission(BasePermission):
message = "必须是SVIP才能访问,你权限太低,滚"
def has_permission(self,request,view):
# request.user 表示获取到 UserInfo 这个类的对象
if request.user.user_type != 3:
return False
return True class MyPermission(BasePermission):
message = "没有权限查看我,滚"
def has_permission(self,request,view):
if request.user.user_type == 3:
return False
return True

  

再看看order信息吧

二 权限源码流程

(1)dispatch

def dispatch(self, request, *args, **kwargs):
"""
`.dispatch()` is pretty much the same as Django's regular dispatch,
but with extra hooks for startup, finalize, and exception handling.
"""
self.args = args
self.kwargs = kwargs
#对原始request进行加工,丰富了一些功能
#Request(
# request,
# parsers=self.get_parsers(),
# authenticators=self.get_authenticators(),
# negotiator=self.get_content_negotiator(),
# parser_context=parser_context
# )
#request(原始request,[BasicAuthentications对象,])
#获取原生request,request._request
#获取认证类的对象,request.authticators
#1.封装request
request = self.initialize_request(request, *args, **kwargs)
self.request = request
self.headers = self.default_response_headers # deprecate? try:
#2.认证
self.initial(request, *args, **kwargs) # Get the appropriate handler method
if request.method.lower() in self.http_method_names:
handler = getattr(self, request.method.lower(),
self.http_method_not_allowed)
else:
handler = self.http_method_not_allowed response = handler(request, *args, **kwargs) except Exception as exc:
response = self.handle_exception(exc) self.response = self.finalize_response(request, response, *args, **kwargs)
return self.response

  

(2)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
#4.实现认证
self.perform_authentication(request)
#5.权限判断
self.check_permissions(request)
self.check_throttles(request)

  

(3)check_permissions

里面有个has_permission这个就是我们自己写的权限判断

def check_permissions(self, request):
"""
Check if the request should be permitted.
Raises an appropriate exception if the request is not permitted.
"""
#[权限类的对象列表]
for permission in self.get_permissions():
if not permission.has_permission(request, self):
self.permission_denied(
request, message=getattr(permission, 'message', None)
)

  

(4)get_permissions

 def get_permissions(self):
"""
Instantiates and returns the list of permissions that this view requires.
"""
return [permission() for permission in self.permission_classes]

 

 

所以settings全局配置就如下

#全局
REST_FRAMEWORK = {
"DEFAULT_PERMISSION_CLASSES":['API.utils.permission.SVIPPremission'],
}

  

三 内置权限

django-rest-framework内置权限BasePermission

默认是没有限制权限

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,修改之前写的permission.py文件

# utils/permission.py

from rest_framework.permissions import BasePermission

class SVIPPremission(BasePermission):
message = "必须是SVIP才能访问"
def has_permission(self,request,view):
if request.user.user_type != 3:
return False
return True class MyPremission(BasePermission):
def has_permission(self,request,view):
if request.user.user_type == 3:
return False
return True

  

总结:

(1)使用

  • 自己写的权限类:1.必须继承BasePermission类;  2.必须实现:has_permission方法

(2)返回值

  • True   有权访问
  • False  无权访问

(3)局部

  • permission_classes = [MyPremission,]

(4)全局

REST_FRAMEWORK = {
#权限
"DEFAULT_PERMISSION_CLASSES":['API.utils.permission.SVIPPremission'],
}

  

好了,权限这边还是so easy 的。

Django rest framework(2)----权限的更多相关文章

  1. Django Rest framework 之 权限

    django rest framework 之 认证(一) django rest framework 之 权限(二) django rest framework 之 节流(三) django res ...

  2. Django REST framework认证权限和限制和频率

    认证.权限和限制 身份验证是将传入请求与一组标识凭据(例如请求来自的用户或其签名的令牌)相关联的机制.然后 权限 和 限制 组件决定是否拒绝这个请求. 简单来说就是: 认证确定了你是谁 权限确定你能不 ...

  3. Django Rest Framework之权限

    基本代码结构 url.py: from django.conf.urls import url, include from app import views urlpatterns = [ url(r ...

  4. Django REST Framework 认证 - 权限 - 限制

    一. 认证 (你是谁?) REST framework 提供了一些开箱即用的身份验证方案,并且还允许你实现自定义方案. 自定义Token认证 第一步 : 建表>>>> 定义一个 ...

  5. Django REST Framework之权限组件

    权限控制是如何实现的? 一般来说,先有认证才有权限,也就是用户登录后才能判断其权限,未登录用户给他一个默认权限. Django接收到一个请求,首先经过权限的检查,如果通过检查,拥有访问的权限,则予以放 ...

  6. Django REST framework认证权限和限制 源码分析

    1.首先 我们进入这个initial()里面看下他内部是怎么实现的. 2.我们进入里面看到他实现了3个方法,一个认证,权限频率 3.我们首先看下认证组件发生了什么 权限: 啥都没返回,self.per ...

  7. Django Rest Framework源码剖析(二)-----权限

    一.简介 在上一篇博客中已经介绍了django rest framework 对于认证的源码流程,以及实现过程,当用户经过认证之后下一步就是涉及到权限的问题.比如订单的业务只能VIP才能查看,所以这时 ...

  8. Django Rest framework 之 序列化

    RESTful 规范 django rest framework 之 认证(一) django rest framework 之 权限(二) django rest framework 之 节流(三) ...

  9. Django Rest framework 之 解析器

    RESTful 规范 django rest framework 之 认证(一) django rest framework 之 权限(二) django rest framework 之 节流(三) ...

  10. Django Rest framework 之 版本

    RESTful 规范 django rest framework 之 认证(一) django rest framework 之 权限(二) django rest framework 之 节流(三) ...

随机推荐

  1. bzoj1658: [Usaco2006 Mar]Water Slides 滑水

    Description It's a hot summer day, and Farmer John is letting Betsy go to the water park where she i ...

  2. 20145303刘俊谦《网络攻防》Exp4 Msf基础

    20145303刘俊谦<网络攻防>Exp4 Msf基础 实验目标 • 掌握metasploit的基本应用方式,掌握常用的三种攻击方式的思路. • 一个主动攻击,如ms08_067: • 一 ...

  3. 牛客网试卷: 京东2019校招笔试Java开发工程师笔试题(1-)

    1.在软件开发过程中,我们可以采用不同的过程模型,下列有关 增量模型描述正确的是() A 是一种线性开发模型,具有不可回溯性 B 把待开发的软件系统模块化,将每个模块作为一个增量组件,从而分批次地分析 ...

  4. Python3基础 list 推导式 生成与已知列表等长度+元素为0的列表

             Python : 3.7.0          OS : Ubuntu 18.04.1 LTS         IDE : PyCharm 2018.2.4       Conda ...

  5. 九数组分数|2015年蓝桥杯B组题解析第五题-fishers

    九数组分数 1,2,3...9 这九个数字组成一个分数,其值恰好为1/3,如何组法? 下面的程序实现了该功能,请填写划线部分缺失的代码. #include <stdio.h> void t ...

  6. environment variable is too large 2047

    https://stackoverflow.com/questions/34491244/environment-variable-is-too-large-on-windows-10 方案1 Whe ...

  7. Luogu P1314 聪明的质监员 二分答案

    题目链接 Solution 这个范围不是二分就是结论题就是数学题... 然后再看一会差不多就可以看出来有单调性所以就可以确定二分的解法了 二分那个$W$,用前缀和$O(n+m)$的时间来求出对答案的贡 ...

  8. BZOJ3300: [USACO2011 Feb]Best Parenthesis 模拟

    Description Recently, the cows have been competing with strings of balanced  parentheses and compari ...

  9. 《EMCAScript6入门》读书笔记——22.Module的语法

  10. ElasticSearch 5.4 安装

        1. 前期准备  环境准备 IP地址 操作系统 内存 192.168.1.10 centos 7 16 192.168.1.11 centos 7 16 192.168.1.12 centos ...