一、自动签发

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. .NET 5 尝鲜 - 开源项目TerminalMACS WPF管理端支持.NET 5

    .NET 5 尝鲜 - 开源项目TerminalMACS WPF管理端支持.NET 5 一个使用 Prism 作为模块化框架.基于多个开源控件库作为UI控件选择.集成开源 UI 界面设计的 .NET ...

  2. vue学习第二天:Vue跑马灯效果制作

    分析: 1. 给开始按钮绑定一个点击事件 2.在按钮的事件处理函数中,写相关的业务代码 3.拿到msg字符串 4.调用字符串的substring来进行字符串的截取操作 5.重新赋值利用vm实例的特性来 ...

  3. Jmeter之仿真高并发测试-集合点

    场景: 大家在使用Jmeter测试的时候应该发现了, (1)线程启动了就会直接发送测试请求:--如果要模拟在一瞬间高并发量测试的时候,需要调高线程数量,这很耗测试机器的性能,往往无法支持较大的并发数, ...

  4. spring boot actuator端点高级进阶metris指标详解、git配置详解、自定义扩展详解

    https://www.cnblogs.com/duanxz/p/3508267.html 前言 接着上一篇<Springboot Actuator之一:执行器Actuator入门介绍>a ...

  5. android异步任务asyncTask详细分析

    android中的耗时操作需要放在子线程中去执行 asynctask是对Handler和和线程池的封装,直接使用比THread效率更加的高效因为封装了线程池,比我们每次直接new Thread效率更高 ...

  6. PHP时间处理汇总

    PHP时间处理汇总 1.求上个月的开始时间和结束时间 <?php header('Content-Type: text/html; charset=utf-8'); // 上个月的开始时间 $b ...

  7. SqlServer2016 startengine错误的解决方式整理

    因为某些需要,最近在安装SqlServer2016,但总是安装失败,按照网上各路大佬的解决方案都没有成功.报错提示为两个:无法获取数据库引擎句柄,无法恢复数据库引擎服务.按照网上做法,使用admini ...

  8. python三大神器之fabric

    Fabric Fabric是一个python的远程执行shell的库,同时它也是一个命令行工具.它提供了丰富的同 SSH 交互的接口,可以用来在本地或远程机器上自动化.流水化地执行 Shell 命令. ...

  9. pycharm中导入包失败的解决办法

    将鼠标移动到requests处,出现如下提示 按住alt+enter键,点击install package requests即可安装requests包 安装成功后

  10. 执行python 爬虫脚本时提示bs4.FeatureNotFound: Couldn't find a tree builder with the features you requested: lxml. Do you need to install a parser library?

    from bs4 import BeautifulSoupfrom urllib.request import urlopenimport re html = urlopen('http://**** ...