drf☞jwt自动签发与手动签发
一、自动签发
urls
from rest_framework_jwt.views import obtain_jwt_token
# 使用jwt自带的登录视图
urlpatterns = [
path('login/', obtain_jwt_token),
]
settings
import datetime
JWT_AUTH={
# 配置响应格式,必须和自动签发使用
'JWT_RESPONSE_PAYLOAD_HANDLER':'app01.utils.my_jwt_response_payload_handler',
'JWT_EXPIRATION_DELTA': datetime.timedelta(days=7), # 过期时间,手动配置
}
utils
# 重写jwt响应格式(需要到settings配置)
# 与之配合使用的必须是自动签发
def my_jwt_response_payload_handler(token, user=None, request=None): # 返回什么,前端就能看到什么样子
return {
'token': token,
'msg':'登录成功',
'status':100,
'username':user.username
}
然后直接在前端提交post请求发送账号和密码,会返回我们定义好的响应格式
{
"token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyX2lkIjoxLCJ1c2VybmFtZSI6Imh6IiwiZXhwIjoxNTk1NDE1MTEyLCJlbWFpbCI6IiJ9.BxBdsm6oBz8iPAwSSpo_7IaU4pBp6RjK4c0GJ_FYN1E",
"msg": "登录成功",
"status": 100,
"username": "hz"
}
然后拿出token对测试类发送测试请求
class TestAPI(APIView):
def get(self,request):
print(request.user)
return Response("ok")
# 因为内置的他没有对匿名用户设置拦截,素以匿名用户也能看到ok
# 我们用request.user来区分
# 这里可能会出现我登录了很多次,用每次不同的token都能登录
# 这是因为token校验的是规则,是要加密规则符合且没有超时,那用哪次token都一样的
二、手动签发
utils
from rest_framework_jwt.authentication import BaseJSONWebTokenAuthentication,jwt_decode_handler
import jwt
from rest_framework.exceptions import AuthenticationFailed
class MyAuthentication(BaseJSONWebTokenAuthentication):
# 这里重写的逻辑和BaseJSONWebTokenAuthentication里的authenticate一模一样
def authenticate(self, request):
jwt_token = request.META.get('HTTP_AUTHORIZATION') # 获取浏览器传来的token
if jwt_token:
try:
payload = jwt_decode_handler(jwt_token) # 传入token,拿出第二段用户信息,有内置的校验token功能
except jwt.ExpiredSignature:
raise AuthenticationFailed('签名过期')
except jwt.InvalidTokenError:
raise AuthenticationFailed('用户非法')
except Exception as e:
# 所有异常都会走到这
raise AuthenticationFailed(str(e))
# 通过内置的方法把payload转换成用户对象
user = self.authenticate_credentials(payload)
return user,None # ===》request.user,request.auth
raise AuthenticationFailed('您没有携带认证信息')
sers
from rest_framework import serializers
# 多方序列化校验登录
import re
from rest_framework.exceptions import ValidationError
from app01 import models
from rest_framework_jwt.utils import jwt_encode_handler,jwt_payload_handler
class LoginSer(serializers.ModelSerializer):
# 我们要提交校验数据的时候,如果直接用下面Meta绑定给模型类的话
# 关键点2:这里如果不写username的话,序列化器直接用的是模型类的username
# 这两者的区别在于,如果覆盖写了username,他表示的可以是任何前端传来的数据,如果是模型类绑定,那只能是用户名了
# 我们这里username用于多方登录的校验数据,必须要重写
# 而password不用重写,因为password用的就是模型类本身的
username = serializers.CharField()
class Meta:
model = models.User
fields =['username','password']
def validate(self, attrs):
username = attrs.get('username')
password = attrs.get('password')
if username:
if re.match('^1[3-9][0-9]{9}$', username):
user = models.User.objects.filter(mobile=username).first()
elif re.match('^.+@.+$', username): # 邮箱
user = models.User.objects.filter(email=username).first()
else:
user = models.User.objects.filter(username=username).first()
if user:
if user.check_password(password):
# 关键点3:jwt_payload_handler把用户数据对象转化成用户信息的字典
# jwt_encode_handler把用户信息的字典转化成token
payload = jwt_payload_handler(user)
# print('user:',user,type(user))
token = jwt_encode_handler(payload)
# print('payload:',payload,type(payload))
# print('token:',token)
# 关键点4:如果我们要给序列化器添加数据,让视图函数去使用
# 通常都是传给对象的context属性,当然直接赋值也可以,这只是他给我们提供的传值接口
self.context['token'] = token
self.context['user'] = user
self.user = user
return attrs
else:
raise ValidationError('密码错误')
raise ValidationError('不存在用户')
raise ValidationError('请输入用户名')
views
class LoginApi(ViewSet):
authentication_classes = []
def login(self, request):
# 在调用序列化类给context传数据,可以直接在序列化类中调用
# 关键点1:注意区分序列化传值与反序列化
# 这里只要拿字典取校验数据,那就传给data
# 如果是要把数据对象转化成字典就传给instance
user_ser = sers.LoginSer(data=request.data, context={'request': request})
user_ser.is_valid(raise_exception=True)
token = user_ser.context.get('token')
user = user_ser.context.get('user')
print(user_ser.user)
return Response({'code': 100, 'msg': '登录成功', 'token': token, 'username': user.username})
drf☞jwt自动签发与手动签发的更多相关文章
- drf中的jwt使用与手动签发token、校验用户
jwt认证 1)session存储token,需要数据库参与,耗服务器资源.低效2)缓存存token,需要缓存参与,高效,不易集群3)客户端存token,服务器存签发与交易token的算法,高效,易集 ...
- drf中的jwt使用与手动签发效验
jwt认证 1)session存储token,需要数据库参与,耗服务器资源.低效 2)缓存存token,需要缓存参与,高效,不易集群 3)客户端存token,服务器存签发与交易token的算法,高效, ...
- 9) drf JWT 认证 签发与校验token 多方式登陆 自定义认证规则反爬 admin密文显示
一 .认证方法比较 1.认证规则图 django 前后端不分离 csrf认证 drf 前后端分离 禁用csrf 2. 认证规则演变图 数据库session认证:低效 缓存认证:高效 jwt认证:高效 ...
- DRF框架(八)——drf-jwt手动签发与校验、搜索过滤组件、排序过滤组件、基础分页组件
自定义drf-jwt手动签发和校验 签发token源码入口 前提:给一个局部禁用了所有 认证与权限 的视图类发送用户信息得到token,其实就是登录接口,不然进不了登录页面 获取提交的username ...
- drf-jwt手动签发与校验,drf小组件:过滤、筛选、排序、分页
复习 """ 频率组件:限制接口的访问频率 源码分析:初始化方法.判断是否有权限方法.计数等待时间方法 自定义频率组件: class MyThrottle(SimpleR ...
- drf_jwt手动签发与校验-drf小组件:过滤-筛选-排序-分页
签发token 源码的入口:完成token签发的view类里面封装的方法. 源码中在请求token的时候只有post请求方法,主要分析一下源码中的post方法的实现. settings源码: 总结: ...
- drf JWT认证模块与自定制
JWT模块 在djangorestframework中,有一款扩展模块可用于做JWT认证,使用如下命令进行安装: pip install djangorestframework-jwt 现在,就让我们 ...
- DRF JWT的用法 & Django的自定义认证类 & DRF 缓存
JWT 相关信息可参考: https://www.jianshu.com/p/576dbf44b2ae DRF JWT 的使用方法: 1. 安装 DRF JWT # pip install djang ...
- DRF JWT认证(一)
为什么要使用JWT认证?构成和原理又是什么?怎么还有Base64的事?我都写了
随机推荐
- numpy.stack和numpy.concatenate的区别
在使用numpy进行矩阵运算的时候踩到的坑,原因是不能正确区分numpy.concatenate和numpy.stack在功能上的差异. 先说numpy.concatenate,直接看文档: nump ...
- JSR133提案-修复Java内存模型
目录 1. 什么是内存模型? 2. JSR 133是关于什么的? 3. 再谈指令重排序 4.同步都做了什么? 5. final字段在旧的内存模型中为什么可以改变? 6."初始化安全" ...
- 使用vuex中的store存储数据
Vuex是一个专门为Vue.js应用程序开发的状态管理模式,这个状态自管理应用包括三个模式 state 驱动应用的数据源 view 以声明方式将state映射到视图 actions 响应在view上的 ...
- CSS中可以继承的元素(需要记住)
可以继承的属性很少,只有颜色,文字,字体间距行高对齐方式,和列表的样式可以继承. 所有元素可继承:visibility和cursor. 内联元素可继承:letter-spacing.word-spac ...
- Docker中使用RabbitMQ
安装Docker yum install docker //安装完成以后,可以查看一下docker的版本 docker -v //Docker version 1.13.1, build 64e998 ...
- AsyncOperation和SceneManager.LoadSceneAsync协同加载场景
这篇属于杂记,用于记录不甚理解的AsyncOperation AsyncOperation: //加载进度条 public Silder silder; 加载场景 public void LoginG ...
- 键盘侠Linux干货| ELK(Elasticsearch + Logstash + Kibana) 搭建教程
前言 Elasticsearch + Logstash + Kibana(ELK)是一套开源的日志管理方案,分析网站的访问情况时我们一般会借助 Google / 百度 / CNZZ 等方式嵌入 JS ...
- ODBC 常见数据源配置整理
目录 1. 简介 1.1 ODBC和JDBC 1.2 ODBC配置工具 1.3 ODBC 数据源连接配置 2. MySQL 数据源配置 2.1 配置步骤 2.2 链接参数配置 3. SQLServer ...
- JavaWeb网上图书商城完整项目--BaseServlet
1.以前进行操作的时候,例如我们进行登陆操作我们使用LoginServlet进行处理,进行注册操作我们使用RegisterServlet,很多业务的操作的时候我们就要定义很多个Servlet 有了Ba ...
- redis基础二----操作hash
上面usr就是hash的名字,usr这个hash中存储了key 为id.name和age的值 一个hash相当于一个数据对象,里面可以存储key为id name age的值 2.批量插入一个hash数 ...