JWT的快速使用(simplejwt)

djangorestframework-simplejwt使用

1 快速使用

1.1 配置

# 1 安装
pip install djangorestframework-simplejwt# 2 路由层
from rest_framework_simplejwt.views import token_obtain_pair, token_verify, token_refreshurlpatterns = [path('login/', token_obtain_pair),path('verify/', token_verify),path('refresh/', token_refresh),
]# 3 配置文件
import datetime
SIMPLE_JWT = {# token有效时长'ACCESS_TOKEN_LIFETIME': datetime.timedelta(minutes=30),# token刷新后的有效时间'REFRESH_TOKEN_LIFETIME': datetime.timedelta(days=1),
}# 4 注册app
INSTALLED_APPS = [...'rest_framework_simplejwt',...
]# 5 迁移表,创建超级用户createsuperuser

1.2 测试

http://127.0.0.1:8000/login/

image

http://127.0.0.1:8000/verify/

image

http://127.0.0.1:8000/refresh/

image

1.3 认证

from rest_framework_simplejwt.authentication import JWTAuthentication
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework.permissions import IsAuthenticated
class BookView(APIView):authentication_classes = [JWTAuthentication]permission_classes = [IsAuthenticated]def get(self,request):return Response("ok")

image

2 Simple JWT的默认设置

# JWT配置
SIMPLE_JWT = {'ACCESS_TOKEN_LIFETIME': timedelta(minutes=5),  # Access Token的有效期'REFRESH_TOKEN_LIFETIME': timedelta(days=7),  # Refresh Token的有效期# 对于大部分情况,设置以上两项就可以了,以下为默认配置项目,可根据需要进行调整# 是否自动刷新Refresh Token'ROTATE_REFRESH_TOKENS': False,  # 刷新Refresh Token时是否将旧Token加入黑名单,如果设置为False,则旧的刷新令牌仍然可以用于获取新的访问令牌。需要将'rest_framework_simplejwt.token_blacklist'加入到'INSTALLED_APPS'的配置中'BLACKLIST_AFTER_ROTATION': False,  'ALGORITHM': 'HS256',  # 加密算法'SIGNING_KEY': settings.SECRET_KEY,  # 签名密匙,这里使用Django的SECRET_KEY# 如为True,则在每次使用访问令牌进行身份验证时,更新用户最后登录时间"UPDATE_LAST_LOGIN": False, # 用于验证JWT签名的密钥返回的内容。可以是字符串形式的密钥,也可以是一个字典。"VERIFYING_KEY": "","AUDIENCE": None,# JWT中的"Audience"声明,用于指定该JWT的预期接收者。"ISSUER": None, # JWT中的"Issuer"声明,用于指定该JWT的发行者。"JSON_ENCODER": None, # 用于序列化JWT负载的JSON编码器。默认为Django的JSON编码器。"JWK_URL": None, # 包含公钥的URL,用于验证JWT签名。"LEEWAY": 0, # 允许的时钟偏差量,以秒为单位。用于在验证JWT的过期时间和生效时间时考虑时钟偏差。# 用于指定JWT在HTTP请求头中使用的身份验证方案。默认为"Bearer""AUTH_HEADER_TYPES": ("Bearer",), # 包含JWT的HTTP请求头的名称。默认为"HTTP_AUTHORIZATION""AUTH_HEADER_NAME": "HTTP_AUTHORIZATION", # 用户模型中用作用户ID的字段。默认为"id"。"USER_ID_FIELD": "id",# JWT负载中包含用户ID的声明。默认为"user_id"。"USER_ID_CLAIM": "user_id",# 用于指定用户身份验证规则的函数或方法。默认使用Django的默认身份验证方法进行身份验证。"USER_AUTHENTICATION_RULE": "rest_framework_simplejwt.authentication.default_user_authentication_rule",#  用于指定可以使用的令牌类。默认为"rest_framework_simplejwt.tokens.AccessToken"。"AUTH_TOKEN_CLASSES": ("rest_framework_simplejwt.tokens.AccessToken",),# JWT负载中包含令牌类型的声明。默认为"token_type"。"TOKEN_TYPE_CLAIM": "token_type",# 用于指定可以使用的用户模型类。默认为"rest_framework_simplejwt.models.TokenUser"。"TOKEN_USER_CLASS": "rest_framework_simplejwt.models.TokenUser",# JWT负载中包含JWT ID的声明。默认为"jti"。"JTI_CLAIM": "jti",# 在使用滑动令牌时,JWT负载中包含刷新令牌过期时间的声明。默认为"refresh_exp"。"SLIDING_TOKEN_REFRESH_EXP_CLAIM": "refresh_exp",# 滑动令牌的生命周期。默认为5分钟。"SLIDING_TOKEN_LIFETIME": timedelta(minutes=5),# 滑动令牌可以用于刷新的时间段。默认为1天。"SLIDING_TOKEN_REFRESH_LIFETIME": timedelta(days=1),# 用于生成访问令牌和刷新令牌的序列化器。"TOKEN_OBTAIN_SERIALIZER": "rest_framework_simplejwt.serializers.TokenObtainPairSerializer",# 用于刷新访问令牌的序列化器。默认"TOKEN_REFRESH_SERIALIZER": "rest_framework_simplejwt.serializers.TokenRefreshSerializer",# 用于验证令牌的序列化器。"TOKEN_VERIFY_SERIALIZER": "rest_framework_simplejwt.serializers.TokenVerifySerializer",# 用于列出或撤销已失效JWT的序列化器。"TOKEN_BLACKLIST_SERIALIZER": "rest_framework_simplejwt.serializers.TokenBlacklistSerializer",# 用于生成滑动令牌的序列化器。"SLIDING_TOKEN_OBTAIN_SERIALIZER": "rest_framework_simplejwt.serializers.TokenObtainSlidingSerializer",# 用于刷新滑动令牌的序列化器。"SLIDING_TOKEN_REFRESH_SERIALIZER": "rest_framework_simplejwt.serializers.TokenRefreshSlidingSerializer",
}

3 自定义返回格式

#1 编写序列化类from rest_framework_simplejwt.serializers import TokenObtainPairSerializer
from rest_framework_simplejwt.views import TokenObtainPairViewclass MyTokenObtainPairSerializer(TokenObtainPairSerializer):@classmethoddef get_token(cls, user):token = super().get_token(user)token['name'] = user.usernamereturn tokendef validate(self, attrs):"""自定义返回的格式"""old_data = super().validate(attrs)refresh = self.get_token(self.user)data = {'code': 100,'msg': '登录成功成功','username':self.user.username,'refresh': str(refresh),'access': str(refresh.access_token)}return data# 2 配置文件配置
SIMPLE_JWT = {"TOKEN_OBTAIN_SERIALIZER": "app01.serializers.MyTokenObtainPairSerializer",
}

4 多方式登录

4.1 models.py

# 需要扩写auth的User表,增加手机号字段
# 配置文件配置

4.2 路由

from app01.views import LoginView
urlpatterns = [path('mul_login/', LoginView.as_view()),
]

4.3 视图类

from rest_framework.response import Response
from . import serializersclass LoginView(APIView):def post(self, request, *args, **kwargs):serializer = serializers.LoginSerializer(data=request.data, context={'request': request})serializer.is_valid(raise_exception=True)refresh = serializer.context.get('refresh')access = serializer.context.get('access')return Response({'code': 100, 'msg': '登录成功', 'refresh': refresh, 'access': access})

4.4 序列化类

from rest_framework import serializers
from django.contrib.auth.models import User
from rest_framework.exceptions import ValidationError
from rest_framework_simplejwt.tokens import RefreshTokenclass LoginSerializer(serializers.ModelSerializer):# 登录请求,走的是post方法,默认post方法完成的是create入库校验,所以唯一约束的字段,会进行数据库唯一校验,导致逻辑相悖# 需要覆盖系统字段,自定义校验规则,就可以避免完成多余的不必要校验,如唯一字段校验username = serializers.CharField()class Meta:model = User# 结合前台登录布局:采用账号密码登录,或手机密码登录,布局一致,所以不管账号还是手机号,都用username字段提交的fields = ('username', 'password')def validate(self, attrs):user = self._get_user(attrs)refresh = RefreshToken.for_user(user)self.context['refresh'] = str(refresh)self.context['access'] = str(refresh.access_token)return attrs# 多方式登录def _get_user(self, attrs):username = attrs.get('username')password = attrs.get('password')import reif re.match(r'^1[3-9][0-9]{9}$', username):# 手机登录user = User.objects.filter(mobile=username, is_active=True).first()elif re.match(r'^.+@.+$', username):# 邮箱登录user = User.objects.filter(email=username, is_active=True).first()else:# 账号登录user = User.objects.filter(username=username, is_active=True).first()if user and user.check_password(password):return userraise ValidationError({'user': 'user error'})

4.5 测试

image

5 自定义用户表,手动签发和认证

5.1 签发

表模型

class UserInfo(models.Model):username = models.CharField(max_length=32)password = models.CharField(max_length=32)

路由

from app01.views import MyLoginView
urlpatterns = [path('my_login/', MyLoginView.as_view()),
]

视图类

class MyLoginView(APIView):def post(self, request, *args, **kwargs):serializer = serializers.MyLoginSerializer(data=request.data, context={'request': request})serializer.is_valid(raise_exception=True)refresh = serializer.context.get('refresh')access = serializer.context.get('access')return Response({'code': 100, 'msg': '登录成功', 'refresh': refresh, 'access': access})

序列化类

from rest_framework import serializers
from .models import UserInfo
from rest_framework.exceptions import ValidationError
from rest_framework_simplejwt.tokens import RefreshTokenclass MyLoginSerializer(serializers.ModelSerializer):class Meta:model = UserInfofields = ('username', 'password')def validate(self, attrs):user = self._get_user(attrs)refresh = RefreshToken.for_user(user)self.context['refresh'] = str(refresh)self.context['access'] = str(refresh.access_token)return attrs# 多方式登录def _get_user(self, attrs):username = attrs.get('username')password = attrs.get('password')user = UserInfo.objects.filter(username=username, password=password).first()if not user:raise ValidationError({'user': 'user error'})return user

image

image

5.2 认证

认证类

from .models import UserInfo
from rest_framework.authentication import BaseAuthentication
from rest_framework.exceptions import AuthenticationFailed
from rest_framework_simplejwt.authentication import JWTAuthenticationclass MyJSONWebTokenAuthentication(JWTAuthentication):def authenticate(self, request):jwt_value = request.META.get("HTTP_TOKEN")if not jwt_value:raise AuthenticationFailed('token 字段是必须的')validated_token = self.get_validated_token(jwt_value)print(validated_token['user_id'])user = UserInfo.objects.filter(pk=validated_token['user_id']).first()return user, jwt_value#### 或者
from rest_framework_simplejwt.tokens import AccessToken
class MyJSONWebTokenAuthentication(BaseAuthentication):def authenticate(self, request):jwt_value = request.META.get("HTTP_TOKEN")if not jwt_value:raise AuthenticationFailed('token 字段是必须的')validated_token = AccessToken(jwt_value)print(validated_token['user_id'])user = UserInfo.objects.filter(pk=validated_token['user_id']).first()return user, jwt_value

视图类

from .auth import MyJSONWebTokenAuthentication
class BookView(APIView):authentication_classes = [MyJSONWebTokenAuthentication]# permission_classes = [IsAuthenticated]def get(self, request):print(request.user.username)return Response("ok")

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/317860.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

模型融合之模型堆叠

一、理论 模型堆叠(Model Stacking)是一种集成学习的方法,其本质是将多个基学习器(Individual Learner)的预测结果作为新的特征,再训练一个元学习器(Meta Learner)来进行最终的预测。…

数字化消费新趋势:跨境电商如何满足未来消费者需求?

在数字化浪潮的推动下,全球消费者的行为和期望正在发生根本性的变化。跨境电商作为连接全球的桥梁,不仅促进了商品的自由流通,更需迎接未来数字化消费的新趋势。本文将深入探讨未来数字化消费的趋势,以及跨境电商如何有效满足这些…

【C++ Primer Plus学习记录】switch语句

假设要创建一个屏幕菜单,要求用户从5个选项中选择一个,例如,便宜、适中、昂贵、奢侈、过度。虽然可以扩展if else if else序列来处理这5种情况,但是C的switch语句能够更容易地从大型列表中进行选择。 下面是switch语句的通用格式…

IDEA断点调试

IDEA断点调试 断点调试是一种在程序执行过程中暂停执行并逐步检查代码状态的方法。它允许开发者在程序运行到特定位置时暂停执行,查看变量的值、执行过程和调用栈等信息,从而更好地理解代码的运行情况和解决问题。可以帮助我们查看java底层源代码的执行…

Spring Security及若依安全实现,Java小白入门(九)

背景 一个系统总会遇到安全,权限的问题,并且一坨坨的术语,让人恼火;更恼火的是官方一坨坨的代码实现,理不清剪不断;最最恼火的是你还得重新注入自己的一些实现,比如个性话的用户、个性化的权限…

【普中开发板】基于51单片机音乐盒LCD1602显示( proteus仿真+程序+设计报告+讲解视频)

【普中开发板】基于51单片机音乐盒LCD1602显示( proteus仿真程序设计报告讲解视频) 仿真图proteus7.8及以上 程序编译器:keil 4/keil 5 编程语言:C语言 设计编号:P08 1. 主要功能: 基于51单片机AT89C51/52&#…

【算法与数据结构】763、LeetCode划分字母区间

文章目录 一、题目二、解法三、完整代码 所有的LeetCode题解索引,可以看这篇文章——【算法和数据结构】LeetCode题解。 一、题目 二、解法 思路分析:本题要求为: 1.尽可能多的划分片段2.字母只能出现在一个片段中3.片段连接起来仍然是s&…

RocketMQ5.0Pop消费模式

前言 RocketMQ 5.0 消费者引入了一种新的消费模式:Pop 消费模式,目的是解决 Push 消费模式的一些痛点。 RocketMQ 4.x 之前,消费模式分为两种: Pull:拉模式,消费者自行拉取消息、上报消费结果Push&#x…

L1-083:谁能进图书馆

题目描述 为了保障安静的阅读环境,有些公共图书馆对儿童入馆做出了限制。例如“12 岁以下儿童禁止入馆,除非有 18 岁以上(包括 18 岁)的成人陪同”。现在有两位小/大朋友跑来问你,他们能不能进去?请你写个程…

机器学习笔记 - 偏最小二乘回归 (PLSR)

一、偏最小二乘回归:简介 PLS 方法构成了一个非常大的方法族。虽然回归方法可能是最流行的 PLS 技术,但它绝不是唯一的一种。即使在 PLSR 中,也有多种不同的算法可以获得解决方案。PLS 回归主要由斯堪的纳维亚化学计量学家 Svante Wold 和 Harald Martens 在 20 世纪 80 年代…

智能安全帽定制_基于联发科MT6765安卓核心板方案

智能安全帽:解放双手,实现远程指导和可视化管理 智能安全帽在安全帽的基础功能上,高度集成了摄像头、语音、通信主板等模块,具有高清视频采集、语音通讯、对讲、本地视频存储等功能。它是一款真正意义上解放现场操作人员双手的穿戴…

《Linux系列》Linux磁盘MBR分区扩容

文章目录 Linux磁盘MBR分区扩容1.前言2.控制台磁盘扩容3.分区扩容3.1 fdisk3.2 lsblk3.3 扩容分区 4.扩容文件系统4.1 df4.2 扩容文件系统 Linux磁盘MBR分区扩容 1)参考阿里云扩容分区文档,整理MBR分区扩容 2)本文档适用于MBR分区(fdisk -lu查…