一、自动签发

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. Map 转 json格式 保留null值的解决办法

    Map 转 json格式 保留null值的解决办法 开发中遇到将map数据转json格式,然后map中含null值的键值对都被转没了,所以记录一下,以下是解决方法 使用fastJson进行转换 imp ...

  2. IP地址和端口

    IP地址是网络中计算机的唯一标识.没有IP地址,计算机无法接入互联网. IPv4地址32bit,用点分十进制表示,如202.38.64.3 IPv6地址128bit,用冒号分割十六进制表示,如2001 ...

  3. MongoDB文档(二)--查询

    (一)查询文档 查询文档可以使用以下方法 # 以非结构化的方式显示所有的文档 db.<collectionName>.find(document) # 以结构化的方式显示所有文档 db.& ...

  4. Centos中使用virtualenvwrapper

    Centos中使用virtualenvwrapper python特有的一种软件环境,创建多个python环境,各个环境之间完全隔离,互不影响.它可以用来解决Python项目开发和运行过程中的依赖项和 ...

  5. Thunk函数的使用

    Thunk函数的使用 编译器的求值策略通常分为传值调用以及传名调用,Thunk函数是应用于编译器的传名调用实现,往往是将参数放到一个临时函数之中,再将这个临时函数传入函数体,这个临时函数就叫做Thun ...

  6. Andrew Ng - 深度学习工程师 - Part 1. 神经网络和深度学习(Week 1. 深度学习概论)

     =================第1周 循环序列模型=============== ===1.1 欢迎来到深度学习工程师微专业=== 我希望可以培养成千上万的人使用人工智能,去解决真实世界的实际问 ...

  7. mysql定时备份任务

    简介 在生产环境上,为了避免数据的丢失,通常情况下都会定时的对数据库进行备份.而Linux的crontab指令则可以帮助我们实现对数据库定时进行备份.首先我们来简单了解crontab指令,如果你会了请 ...

  8. 《Elasticsearch 权威指南》阅读笔记

    书籍地址 https://www.elastic.co/guide/cn/elasticsearch/guide/current/languages.html

  9. android 中IntentService的使用场景

    IntentService是继承并处理异步请求的一个类,在IntentService内有一个工作线程来处理耗时操作,启动IntentService的方式和启动传统的Service一样,同时,当任务执行 ...

  10. 【Oracle】arraysize的研究(存在疑问)

    arraysize的研究(存在疑问) SYS@proc> create table aaa (id1 int,id2 int,id3 int,id4 int); Table created. S ...