drf-Authentication认证

## 源码分析

```python
"""
1)APIView的dispath(self, request, *args, **kwargs)
2)dispath方法内 self.initial(request, *args, **kwargs) 进入三大认证
# 认证组件:校验用户 - 游客、合法用户、非法用户
# 游客:代表校验通过,直接进入下一步校验(权限校验)
# 合法用户:代表校验通过,将用户存储在request.user中,再进入下一步校验(权限校验)
# 非法用户:代表校验失败,抛出异常,返回403权限异常结果
self.perform_authentication(request) # 权限组件:校验用户权限 - 必须登录、所有用户、登录读写游客只读、自定义用户角色
# 认证通过:可以进入下一步校验(频率认证)
# 认证失败:抛出异常,返回403权限异常结果
self.check_permissions(request) # 频率组件:限制视图接口被访问的频率次数 - 限制的条件(IP、id、唯一键)、频率周期时间(s、m、h)、频率的次数(3/s)
# 没有达到限次:正常访问接口
# 达到限次:限制时间内不能访问,限制时间达到后,可以重新访问
self.check_throttles(request) 3) 认证组件
Request类的 方法属性 user 的get方法 => self._authenticate() 完成认证 认证的细则:
# 做认证
def _authenticate(self):
# 遍历拿到一个个认证器,进行认证
# self.authenticators配置的一堆认证类产生的认证类对象组成的 list
for authenticator in self.authenticators:
try:
# 认证器(对象)调用认证方法authenticate(认证类对象self, request请求对象)
# 返回值:登陆的用户与认证的信息组成的 tuple
# 该方法被try包裹,代表该方法会抛异常,抛异常就代表认证失败
user_auth_tuple = authenticator.authenticate(self)
except exceptions.APIException:
self._not_authenticated()
raise # 返回值的处理
if user_auth_tuple is not None:
self._authenticator = authenticator
# 如何有返回值,就将 登陆用户 与 登陆认证 分别保存到 request.user、request.auth
self.user, self.auth = user_auth_tuple
return
# 如果返回值user_auth_tuple为空,代表认证通过,但是没有 登陆用户 与 登陆认证信息,代表游客
self._not_authenticated() 4) 权限组件
self.check_permissions(request)
认证细则:
def check_permissions(self, request):
# 遍历权限对象列表得到一个个权限对象(权限器),进行权限认证
for permission in self.get_permissions():
# 权限类一定有一个has_permission权限方法,用来做权限认证的
# 参数:权限对象self、请求对象request、视图类对象
# 返回值:有权限返回True,无权限返回False
if not permission.has_permission(request, self):
self.permission_denied(
request, message=getattr(permission, 'message', None)
)
"""
``` #### 自定义认证类 ```python
"""
1) 创建继承BaseAuthentication的认证类
2) 实现authenticate方法
3) 实现体根据认证规则 确定游客、非法用户、合法用户
4) 进行全局或局部配置 认证规则
i.没有认证信息返回None(游客)
ii.有认证信息认证失败抛异常(非法用户)
iii.有认证信息认证成功返回用户与认证信息元组(合法用户)
"""
``` ##### utils/authentications.py ```python
# 自定义认证类 # 1)继承BaseAuthentication类
# 2)重新authenticate(self, request)方法,自定义认证规则
# 3)认证规则基于的条件:
# 没有认证信息返回None(游客)
# 有认证信息认证失败抛异常(非法用户)
# 有认证信息认证成功返回用户与认证信息元组(合法用户)
# 4)完全视图类的全局(settings文件中)或局部(确切的视图类)配置
from rest_framework.authentication import BaseAuthentication
from rest_framework.exceptions import AuthenticationFailed
from . import models
class MyAuthentication(BaseAuthentication):
"""
同前台请求头拿认证信息auth(获取认证的字段要与前台约定)
没有auth是游客,返回None
有auth进行校验
失败是非法用户,抛出异常
成功是合法用户,返回 (用户, 认证信息)
"""
def authenticate(self, request):
# 前台在请求头携带认证信息,
# 且默认规范用 Authorization 字段携带认证信息,
# 后台固定在请求对象的META字段中 HTTP_AUTHORIZATION 获取
auth = request.META.get('HTTP_AUTHORIZATION', None) # 处理游客
if auth is None:
return None # 设置一下认证字段小规则(两段式):"auth 认证字符串"
auth_list = auth.split() # 校验合法还是非法用户
if not (len(auth_list) == 2 and auth_list[0].lower() == 'auth'):
raise AuthenticationFailed('认证信息有误,非法用户') # 合法的用户还需要从auth_list[1]中解析出来
# 注:假设一种情况,信息为abc.123.xyz,就可以解析出admin用户;实际开发,该逻辑一定是校验用户的正常逻辑
if auth_list[1] != 'abc.123.xyz': # 校验失败
raise AuthenticationFailed('用户校验失败,非法用户') user = models.User.objects.filter(username='admin').first() if not user:
raise AuthenticationFailed('用户数据有误,非法用户')
return (user, None)
``` ```python
# 家庭作业
# 1) 可以采用脚本基于auth组件创建三个普通用户:models.User.objects.create_user()
# 注:直接写出注册接口更好
# 2) 自定义session表:id,u_id,token,为每个用户配置一个固定人认证字符串,可以直接操作数据库
# 注:在注册接口中实现更好
# 3) 自定义认证类,不同的token可以校验出不同的登陆用户
``` #### 系统权限类 ```python
"""
1)AllowAny:
认证规则全部返还True:return True
游客与登陆用户都有所有权限 2) IsAuthenticated:
认证规则必须有登陆的合法用户:return bool(request.user and request.user.is_authenticated)
游客没有任何权限,登陆用户才有权限 3) IsAdminUser:
认证规则必须是后台管理用户:return bool(request.user and request.user.is_staff)
游客没有任何权限,登陆用户才有权限 4) IsAuthenticatedOrReadOnly
认证规则必须是只读请求或是合法用户:
return bool(
request.method in SAFE_METHODS or
request.user and
request.user.is_authenticated
)
游客只读,合法用户无限制
""" # api/views.py
from rest_framework.permissions import IsAuthenticated
class TestAuthenticatedAPIView(APIView):
permission_classes = [IsAuthenticated]
def get(self, request, *args, **kwargs):
return APIResponse(0, 'test 登录才能访问的接口 ok') # 因为默认全局配置的权限类是AllowAny
# settings.py
REST_FRAMEWORK = {
# 权限类配置
'DEFAULT_PERMISSION_CLASSES': [
'rest_framework.permissions.AllowAny',
],
} ``` #### 自定义权限类 ```python
"""
1) 创建继承BasePermission的权限类
2) 实现has_permission方法
3) 实现体根据权限规则 确定有无权限
4) 进行全局或局部配置 认证规则
i.满足设置的用户条件,代表有权限,返回True
ii.不满足设置的用户条件,代表有权限,返回False
"""
``` ```python
# utils/permissions.py
from rest_framework.permissions import BasePermission
from django.contrib.auth.models import Group
class MyPermission(BasePermission):
def has_permission(self, request, view):
# 只读接口判断
r1 = request.method in ('GET', 'HEAD', 'OPTIONS')
# group为有权限的分组
group = Group.objects.filter(name='管理员').first()
# groups为当前用户所属的所有分组
groups = request.user.groups.all()
r2 = group and groups
r3 = group in groups
# 读接口大家都有权限,写接口必须为指定分组下的登陆用户
return r1 or (r2 and r3) # 游客只读,登录用户只读,只有登录用户属于 管理员 分组,才可以增删改
from utils.permissions import MyPermission
class TestAdminOrReadOnlyAPIView(APIView):
permission_classes = [MyPermission]
# 所有用户都可以访问
def get(self, request, *args, **kwargs):
return APIResponse(0, '自定义读 OK')
# 必须是 自定义“管理员”分组 下的用户
def post(self, request, *args, **kwargs):
return APIResponse(0, '自定义写 OK')
```

drf-Authentication认证的更多相关文章

  1. python 全栈开发,Day104(DRF用户认证,结算中心,django-redis)

    考试第二部分:MySQL数据库 6.  MySQL中char和varchar的区别(1分) char是定长,varchar是变长. char的查询速度比varchar要快. 7.   MySQL中va ...

  2. DRF(4) - 认证、权限组件

    一.引入 通过前面三节课的学习,我们已经详细了解了DRF提供的几个重要的工具,DRF充分利用了面向对象编程的思想,对Django的View类进行了继承,并封装了其as_view方法和dispatch方 ...

  3. DRF JWT认证(二)

    快速上手JWT签发token和认证,有这一篇就够了,DRF自带的和自定义的都帮你总结好了,拿去用~

  4. HTTP Basic Authentication认证的各种语言 后台用的

    访问需要HTTP Basic Authentication认证的资源的各种语言的实现 无聊想调用下嘀咕的api的时候,发现需要HTTP Basic Authentication,就看了下. 什么是HT ...

  5. DRF 版本 认证

    DRF的版本 版本控制是做什么用的, 我们为什么要用 首先我们要知道我们的版本是干嘛用的呢大家都知道我们开发项目是有多个版本的 当我们项目越来越更新~版本就越来越多我们不可能新的版本出了~以前旧的版本 ...

  6. HTTP Basic Authentication认证

    http://smalltalllong.iteye.com/blog/912046 ******************************************** 什么是HTTP Basi ...

  7. 访问需要HTTP Basic Authentication认证的资源的各种开发语言的实现

    什么是HTTP Basic Authentication?直接看http://en.wikipedia.org/wiki/Basic_authentication_scheme吧. 在你访问一个需要H ...

  8. DRF的认证,频率,权限

    1,DRF的认证 初识认证:浏览器是无状态的,一次导致每次发的请求都是新的请求,所以每次请求,服务器都会进行校验,这样就很繁琐,这趟我们就需要给每一个用户登录后一个新的标识,浏览器每次都会带着这个唯一 ...

  9. HttpClient 三种 Http Basic Authentication 认证方式,你了解了吗?

    Http Basic 简介 HTTP 提供一个用于权限控制和认证的通用框架.最常用的 HTTP 认证方案是 HTTP Basic authentication.Http Basic 认证是一种用来允许 ...

  10. ASP.NET Core[源码分析篇] - Authentication认证

    原文:ASP.NET Core[源码分析篇] - Authentication认证 追本溯源,从使用开始 首先看一下我们通常是如何使用微软自带的认证,一般在Startup里面配置我们所需的依赖认证服务 ...

随机推荐

  1. ftp上传html文件

    在用ftp上传当个html文件时,发现html文件会被压缩成一行,在html中的单行注释将后面的代码都注释掉了,导致网页不能正常访问. 8uftp.FlashFXP.filezilla 在这三个ftp ...

  2. 完美解决报错Failed to convert value of type 'java.lang.String' to required type 'java.util.Date'

    Failed to convert value of type 'java.lang.String' to required type 'java.util.Date' 首先这个错误的意思是 前台页面 ...

  3. Rocket - debug - Example: DMI

    https://mp.weixin.qq.com/s/7suuJ7m2BKCpsHk1K2FzJQ 介绍riscv-debug的使用实例:如何使用DMI. 1. dm Debug Module实现了调 ...

  4. golang内存逃逸

    golang程序变量会携带油一组校验数据,用来证明它的整个生命周期是否在运行时完全可知.如果变量通过了这些校验,它就可以在栈上分配.否则就说它逃逸了,必须在堆上分配     能引起变量逃逸到堆上的典型 ...

  5. Java实现蓝桥杯历届试题高僧斗法

    历届试题 高僧斗法 时间限制:1.0s 内存限制:256.0MB 提交此题 锦囊1 锦囊2 问题描述 古时丧葬活动中经常请高僧做法事.仪式结束后,有时会有"高僧斗法"的趣味节目,以 ...

  6. Java蓝桥杯 算法提高 九宫格

    算法提高 9-1九宫格 时间限制:1.0s 内存限制:256.0MB 提交此题 问题描述 九宫格.输入1-9这9个数字的一种任意排序,构成3*3二维数组.如果每行.每列以及对角线之和都相等,打印1.否 ...

  7. Java实现算法竞赛入门经典例题-蚂蚁

    问题描述 一根长度为L厘米的木棍上有n只蚂蚁,每只蚂蚁要么朝左爬,要么朝右爬,速度为1厘米/秒. 当两只蚂蚁相撞时,二者同时掉头(掉头时间忽略不计). 给出每只蚂蚁的初始位置和朝向,计算T秒之后每只蚂 ...

  8. SQL Server实现 LeetCode 178 分数排名

    178. 分数排名 SQL架构 编写一个 SQL 查询来实现分数排名.如果两个分数相同,则两个分数排名(Rank)相同.请注意,平分后的下一个名次应该是下一个连续的整数值.换句话说,名次之间不应该有& ...

  9. java实现第五届蓝桥杯排列序数

    排列序数 如果用a b c d这4个字母组成一个串,有4!=24种,如果把它们排个序,每个串都对应一个序号: abcd 0 abdc 1 acbd 2 acdb 3 adbc 4 adcb 5 bac ...

  10. tensorflow2.0学习笔记第一章第二节

    1.2常用函数 本节目标:掌握在建立和操作神经网络过程中常用的函数 # 常用函数 import tensorflow as tf import numpy as np # 强制Tensor的数据类型转 ...