一、自动签发

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自动签发与手动签发的更多相关文章

  1. drf中的jwt使用与手动签发token、校验用户

    jwt认证 1)session存储token,需要数据库参与,耗服务器资源.低效2)缓存存token,需要缓存参与,高效,不易集群3)客户端存token,服务器存签发与交易token的算法,高效,易集 ...

  2. drf中的jwt使用与手动签发效验

    jwt认证 1)session存储token,需要数据库参与,耗服务器资源.低效 2)缓存存token,需要缓存参与,高效,不易集群 3)客户端存token,服务器存签发与交易token的算法,高效, ...

  3. 9) drf JWT 认证 签发与校验token 多方式登陆 自定义认证规则反爬 admin密文显示

    一 .认证方法比较 1.认证规则图 django 前后端不分离 csrf认证 drf 前后端分离 禁用csrf 2. 认证规则演变图 数据库session认证:低效 缓存认证:高效 jwt认证:高效 ...

  4. DRF框架(八)——drf-jwt手动签发与校验、搜索过滤组件、排序过滤组件、基础分页组件

    自定义drf-jwt手动签发和校验 签发token源码入口 前提:给一个局部禁用了所有 认证与权限 的视图类发送用户信息得到token,其实就是登录接口,不然进不了登录页面 获取提交的username ...

  5. drf-jwt手动签发与校验,drf小组件:过滤、筛选、排序、分页

    复习 """ 频率组件:限制接口的访问频率 源码分析:初始化方法.判断是否有权限方法.计数等待时间方法 自定义频率组件: class MyThrottle(SimpleR ...

  6. drf_jwt手动签发与校验-drf小组件:过滤-筛选-排序-分页

    签发token 源码的入口:完成token签发的view类里面封装的方法. 源码中在请求token的时候只有post请求方法,主要分析一下源码中的post方法的实现. settings源码: 总结: ...

  7. drf JWT认证模块与自定制

    JWT模块 在djangorestframework中,有一款扩展模块可用于做JWT认证,使用如下命令进行安装: pip install djangorestframework-jwt 现在,就让我们 ...

  8. DRF JWT的用法 & Django的自定义认证类 & DRF 缓存

    JWT 相关信息可参考: https://www.jianshu.com/p/576dbf44b2ae DRF JWT 的使用方法: 1. 安装 DRF JWT # pip install djang ...

  9. DRF JWT认证(一)

    为什么要使用JWT认证?构成和原理又是什么?怎么还有Base64的事?我都写了

随机推荐

  1. 10.实战交付一套dubbo微服务到k8s集群(3)之二进制安装Maven

    maven官网:https://maven.apache.org/ maven二进制下载连接:https://archive.apache.org/dist/maven/maven-3/3.6.1/b ...

  2. TiDB初探

    TiDB是一个开源的分布式NewSQL数据库,设计的目标是满足100%的OLTP和80%的OLAP,支持SQL.水平弹性扩展.分布式事务.跨数据中心数据强一致性保证.故障自恢复的高可用.海量数据高并发 ...

  3. .NET Core Hangfire周期性作业调度问题

    前言 四月中旬Hangfire团队发布了1.7.11版本,在使用周期性作业调度过程中发现一个问题,这个问题应该一直未解决,故做此记录,希望遇到的童鞋根据项目业务而避开这个问题. 周期性作业调度 我们依 ...

  4. MapReduce 论文阅读笔记

    Abstract MapReduce : programming model 编程模型 an associated implementation for processing and generati ...

  5. 常用电子邮件协议服务POP3/IMAP/SMTP/Exchange

    标题: 常用电子邮件协议服务POP3/IMAP/SMTP/Exchange 作者: 梦幻之心星 347369787@QQ.com 标签: [电子邮件, 服务, 协议] 目录: [客户端] 日期: 20 ...

  6. 设计模式系列之代理模式(Proxy Pattern)——对象的间接访问

    说明:设计模式系列文章是读刘伟所著<设计模式的艺术之道(软件开发人员内功修炼之道)>一书的阅读笔记.个人感觉这本书讲的不错,有兴趣推荐读一读.详细内容也可以看看此书作者的博客https:/ ...

  7. java后端无法接收到前端传递的json对象

    java后端无法接收到前端传递的json对象 一·可能是因为未使用@RequestBody 在Controller层中,要么使用@RestController要么使用@Controller+@@Req ...

  8. Convert to Ones

    Convert to Ones 'You've got a string a 1 , a 2 ,-, a n a1,a2,-,an , consisting of zeros and ones. Le ...

  9. Spring 获取单例流程(二)

    读完这篇文章你将会收获到 Spring 中 prototype 类型的 bean 如何做循环依赖检测 Spring 中 singleton 类型的 bean 如何做循环依赖检测 前言 继上一篇文章 S ...

  10. Pytest 单元测试框架标记用例

    1.Pytest 中标记用例 接参数 -k 来挑选要执行的测试项 pytest -k test_szdcs -s test_szdcs 为函数名称 -k 后面接的名称可以为函数名称.类名称.文件名称. ...