Django drf:认证及组件、token、局部钩子源码分析
一、drf认证功能
二、token讲解
三、局部钩子源码分析
一、drf认证功能
1.认证简介:
只有认证通过的用户才能访问指定的url地址,比如:查询课程信息,需要登录之后才能查看,没有登录则不能查看。这时候需要用到认证组件
2.局部使用
models层
class User(models.Model):
name = models.CharField(max_length=32)
password = models.CharField(max_length=32) class UserToken(models.Model):
token = models.CharField(max_length=64)
user = models.OneToOneField(to='User')
新建认证类(验证通过return两个参数)
from rest_framework.authentication import BaseAuthentication class Authlogin(BaseAuthentication):
def authenticate(self, request):
token = request.GET.get('token')
res = models.UserToken.objects.filter(token=token).first()
if res:
# 说明这个人登录了
# return None
return res.user, token
else:
# 说明没有登录
raise NotAuthenticated("您没有登录")
views层
def get_token(name):
m = hashlib.md5(name.encode("utf-8"))
print(m.hexdigest())
res = m.hexdigest()
return res class Login(APIView):
#authentication_classes = []
def post(self, request):
response = {'status': 100, 'msg': None}
# 把用户名和密码取到
name = request.data.get('name')
pwd = request.data.get('password')
print(name, pwd)
# 取出数据库的用户数据
user = models.User.objects.filter(name=name, password=pwd).first()
print(user)
if user:
response['msg'] = '登录成功!'
# 随机字符串可以是用户名+当前同时生成md5
# uuid
token = get_token(name) # user = user 查询条件 defaults={'token':token}
models.UserToken.objects.update_or_create(user=user, defaults={'token': token})
response['token'] = token
else:
# response['status']后面是等于号不是冒号
response['status'] = 101
print(response['status'])
response['msg'] = '用户名或密码错误'
return Response(response)
def get_token(id,salt=''):
import hashlib
md=hashlib.md5()
md.update(bytes(str(id),encoding='utf-8'))
md.update(bytes(salt,encoding='utf-8')) return md.hexdigest()+'|'+str(id) def check_token(token,salt=''):
ll=token.split('|')
import hashlib
md=hashlib.md5()
md.update(bytes(ll[-1],encoding='utf-8'))
md.update(bytes(salt,encoding='utf-8'))
if ll[0]==md.hexdigest():
return True
else:
return False class TokenAuth():
def authenticate(self, request):
token = request.GET.get('token')
success=check_token(token)
if success:
return
else:
raise AuthenticationFailed('认证失败')
def authenticate_header(self,request):
pass
class Login(APIView):
def post(self,reuquest):
back_msg={'status':1001,'msg':None}
try:
name=reuquest.data.get('name')
pwd=reuquest.data.get('pwd')
user=models.User.objects.filter(username=name,password=pwd).first()
if user:
token=get_token(user.pk)
# models.UserToken.objects.update_or_create(user=user,defaults={'token':token})
back_msg['status']=''
back_msg['msg']='登录成功'
back_msg['token']=token
else:
back_msg['msg'] = '用户名或密码错误'
except Exception as e:
back_msg['msg']=str(e)
return Response(back_msg)
from rest_framework.authentication import BaseAuthentication
class TokenAuth():
def authenticate(self, request):
token = request.GET.get('token')
token_obj = models.UserToken.objects.filter(token=token).first()
if token_obj:
return
else:
raise AuthenticationFailed('认证失败')
def authenticate_header(self,request):
pass class Course(APIView):
authentication_classes = [TokenAuth, ] def get(self, request):
return HttpResponse('get') def post(self, request):
return HttpResponse('post')
不存数据库的token验证
-把{name:lqz,id:1} 用我自己知道的加密方式加密之后变成了:asdfasdf
-asdfasdf|{name:lqz,id:1} 当做token,发到客户端
-以后客户端再发请求,会携带asdfasdf|{name:lqz,id:1}过来
-服务端截取{name:lqz,id:1},再用我的加密方式加密:asdfasdf
-拿到加密后的串:asdfasdf和请求的asdfasdf比较,如果一样
bsdfasdf|{name:lqz,id:1}
-token好处是:服务端不需要存session了
总结:局部使用,只需要在试图类里加入
authentication_classes = [TokenAuth, ]
3.全局使用
*一般会将继承BaseAuthentication的token类抽出来单独放在一个auth.py文件中
from rest_framework.authentication import BaseAuthentication
from rest_framework.exceptions import NotAuthenticated
from app import models class Authlogin(BaseAuthentication):
def authenticate(self, request):
token = request.GET.get('token')
res = models.UserToken.objects.filter(token=token).first()
if res:
# 说明这个人登录了
# return None
return res.user, token
else:
# 说明没有登录
raise NotAuthenticated("您没有登录")
*在setting文件中配置全局认证属性
# ["app.auth.Authlogin", ]中的Authlogin要与auth.py文件中视图类大小写一致
REST_FRAMEWORK = {
"DEFAULT_AUTHENTICATION_CLASSES": ["app.auth.Authlogin", ]
}
* 需要在login中加入局部禁用
authentication_classes = []
二、token讲解
-认证功能:
1 写一个类,继承BaseAuthentication
2 def authenticate(self,request) ,记住传request对象
-如果验证通过,返回None或者两个值
3 在视图类中使用:(不要加括号)
authentication_classes=[AuthLogin]
-认证功能的局部配置
-authentication_classes=[AuthLogin]
-认证功能的全局配置,在settings.py中配置
-REST_FRAMEWORK={
"DEFAULT_AUTHENTICATION_CLASSES":["app01.auth.AuthLogin",]
}
-全局使用的局部禁用:
authentication_classes = []
-drf内置了一些认证类(了解):
-TokenAuthentication
-SessionAuthentication
#BaseAuthentication(规范了接口,模拟其它语言接口的概念)
def authenticate(self, request):
raise NotImplementedError(".authenticate() must be overridden.")
# 如果写了一个类,继承BaseAuthentication,但是没有重写authenticate,就会抛异常
三、局部钩子源码分析
# 通过is_valid的父级查找到serializers

# 找到该文件下的to_internal_value方法

# 走完后走run_validation功能


Django drf:认证及组件、token、局部钩子源码分析的更多相关文章
- django身份认证、权限认证、频率校验使用及源码分析
一. 身份认证源码分析 1.1 APIView源码的分析 APIView源码之前分析过https://www.cnblogs.com/maoruqiang/p/11135335.html,里面主要将r ...
- Django的rest_framework认证组件之局部设置源码解析
前言: Django的rest_framework组件的功能很强大,今天来我来给大家剖析一下认证组件 下面进入正文分析,我们从视图开始,一步一步来剖析认证组件 1.进入urls文件 url(r'^lo ...
- 序列化器中钩子函数源码分析、many关键字源码分析
局部钩子和全局钩子源码分析(2星) # 入口是 ser.is_valid(),是BaseSerializer的方法 # 最核心的代码 self._validated_data = self.run_v ...
- Django(60)Django内置User模型源码分析及自定义User
前言 Django为我们提供了内置的User模型,不需要我们再额外定义用户模型,建立用户体系了.它的完整的路径是在django.contrib.auth.models.User. User模型源码分析 ...
- Django drf:序列化增删改查、局部与全局钩子源码流程、认证源码分析、执行流程
一.序列化类的增.删.改.查 用drf的序列化组件 -定义一个类继承class BookSerializer(serializers.Serializer): -写字段,如果不指定source ...
- Django框架(十五)—— forms组件、局部钩子、全局钩子
目录 forms组件.局部钩子.全局钩子 一.什么是forms组件 二.forms组件的使用 1.使用语法 2.组件的参数 3.注意点 三.渲染模板 四.渲染错误信息 五.局部钩子 1.什么是局部钩子 ...
- Django REST framework —— 认证组件源码分析
我在前面的博客里已经讲过了,我们一般编写API的时候用的方式 class CoursesView(ViewSetMixin,APIView): pass 这种方式的有点是,灵活性比较大,可以根据自己的 ...
- Django rest framework源码分析(1)----认证
目录 Django rest framework(1)----认证 Django rest framework(2)----权限 Django rest framework(3)----节流 Djan ...
- Django-restframework 源码之认证组件源码分析
Django-restframework 源码之认证组件源码分析 一 前言 之前在 Django-restframework 的流程分析博客中,把最重要的关于认证.权限和频率的方法找到了.该方法是 A ...
随机推荐
- python面向对象之封装,继承,多态
封装,顾名思义就是将内容封装到某个地方,以后再去调用被封装在某处的内容.在python的类中,封装即通过__init__函数将数据赋给对应的变量进行保存,便于其他地方使用 所以,在使用面向对象的封装特 ...
- [c++]C++关键字之friend
re 1. C++关键字之friend; end 希望大家能把自己的所学和他人一起分享,不要去鄙视别人索取时的贪婪,因为最应该被鄙视的是不肯分享时的吝啬.---GOOD---
- Python3之返回函数
参考:https://www.cnblogs.com/mzc1997/p/7641995.html Python中函数不仅可以作为参数还可以作为结果返回 >>> def pro1(c ...
- Zuul1与Spring Cloud Gateway对比
一.API网关 1.1 Zuul1简介 1.2 Spring Cloud Gateway简介 二.对比 2.0 产品对比 2.1 性能对比 2.1.1 低并发场景 2.1.2 高并发场景 2.1.3 ...
- 【实验】ssh私钥泄露
翻自己的笔记看到之前做过的一个实验,一个关于ssh私钥泄露的实验,贴出来与大家交流. 做这种题脑洞需要特别大,而且也需要运气. 1.实验环境准备 2.实验流程 1)探测信息 用namp进行端口扫描,扫 ...
- 高级UI-Palette
Google推出的Palette是用来调色的,正如其汉语意思一样,可以用来显示颜色,在显示图片的时候,会配合图片的色调来显示,这样就显得很融合,其实Palette可以分析出图片中的很多特性,例如主色调 ...
- web 中常用的两种上传文件的方法总结
这里我们来总结整理一下常用的两种文件上传方式以及要注意的东西: 1.springmvc .MultipartFile 的上传方式. 2.org.apache.commons.fileupload 使用 ...
- upw,c#,启用后台播放控件
uwp音视频app,启用后台播放控件. 启用控件 SystemMediaTransportControls systemMedia_TransportControls = SystemMediaTra ...
- Chrome 浏览器光标定位到地址栏
Windows: Ctrl + L 或 Alt + D Mac: Command + L Linux: Ctrl + L
- Word 查找替换高级玩法系列之 -- 给数字批量添加空格和下划线
Word中的查找和替换是一个很强大的功能,很多人都在使用这项功能.查找和替换,顾名思义就是说,查找到符合条件的内容,然后将那些内容替换成我们所需要的内容.下面,我们就通过实例来了解一下查找和替换功能, ...