简介:如何利用simplejwt实现认证登录
首先需要创建好一个完整的DRF项目。simplejwt是基于DRF的Token认证。
simplejwt教程
1、安装simpleJWT
pip install djangorestframework-simplejwt
2、项目配置
在setting.py中添加
REST_FRAMEWORK = {
...
'DEFAULT_AUTHENTICATION_CLASSES': (
...
'rest_framework_simplejwt.authentication.JWTAuthentication',
)
...
}
添加simplejwt的相关配置(简单配置)
SIMPLE_JWT = {
'ACCESS_TOKEN_LIFETIME': timedelta(minutes=60), # Access token 过期时间,这里设置为60分钟
'REFRESH_TOKEN_LIFETIME': timedelta(days=1), # Refresh token 过期时间,这里设置为1天
'ROTATE_REFRESH_TOKENS': False, # 是否在每次刷新时生成新的 refresh token
'BLACKLIST_AFTER_ROTATION': True, # 刷新后是否将旧的 refresh token 加入黑名单
'ALGORITHM': 'HS256', # 使用的哈希算法
}
JWT完整的配置(各类行为和属性)
# 配置访问令牌的生命周期,这里设置为5分钟
"ACCESS_TOKEN_LIFETIME": timedelta(minutes=5),
# 配置刷新令牌的生命周期,这里设置为1天
"REFRESH_TOKEN_LIFETIME": timedelta(days=1),
# 是否允许刷新令牌旋转,这里设置为不允许
"ROTATE_REFRESH_TOKENS": False,
# 旋转刷新令牌后是否将其加入黑名单,这里设置为不允许
"BLACKLIST_AFTER_ROTATION": False,
# 是否在用户成功登录后更新最后登录时间,这里设置为不允许
"UPDATE_LAST_LOGIN": False,
# 配置JWT的签名算法,这里使用HS256
"ALGORITHM": "HS256",
# 配置用于签名的密钥,这里使用Django的SECRET_KEY
"SIGNING_KEY": settings.SECRET_KEY,
# 配置用于验证的密钥,这里留空
"VERIFYING_KEY": "",
# 配置JWT的受众,这里不进行配置
"AUDIENCE": None,
# 配置JWT的发行者,这里不进行配置
"ISSUER": None,
# 自定义JSON编码器,这里不进行配置
"JSON_ENCODER": None,
# 配置JWK URL,这里不进行配置
"JWK_URL": None,
# 配置JWT的宽限期,这里设置为0
"LEEWAY": 0,
# 配置认证头的类型,这里只允许Bearer类型
"AUTH_HEADER_TYPES": ("Bearer",),
# 配置认证头的名称,这里使用HTTP标准
"AUTH_HEADER_NAME": "HTTP_AUTHORIZATION",
# 配置用户ID字段,这里使用id
"USER_ID_FIELD": "id",
# 配置用户ID在JWT中的声明名称
"USER_ID_CLAIM": "user_id",
# 配置用户认证规则,这里使用默认规则
"USER_AUTHENTICATION_RULE": "rest_framework_simplejwt.authentication.default_user_authentication_rule",
# 配置认证令牌类,这里使用AccessToken
"AUTH_TOKEN_CLASSES": ("rest_framework_simplejwt.tokens.AccessToken",),
# 配置令牌类型在JWT中的声明名称
"TOKEN_TYPE_CLAIM": "token_type",
# 配置令牌用户类,这里使用TokenUser
"TOKEN_USER_CLASS": "rest_framework_simplejwt.models.TokenUser",
# 配置JWT唯一标识符在JWT中的声明名称
"JTI_CLAIM": "jti",
# 配置滑动令牌的刷新过期声明名称
"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",
# 配置将令牌加入黑名单的序列化器,这里使用默认序列化器
"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",
在url .py中使用TokenObtainPairView, TokenRefreshView视图 实现Token的获取和刷新
from rest_framework_simplejwt.views import (
TokenObtainPairView,
TokenRefreshView,
)
urlpatterns = [
...
path('api/token/', TokenObtainPairView.as_view(), name='token_obtain_pair'),
path('api/token/refresh/', TokenRefreshView.as_view(), name='token_refresh'),
...
]
Simple JWT 的路由允许API用户验证HMAC 签名的令牌,而无需访问。
from rest_framework_simplejwt.views import TokenVerifyView
urlpatterns = [
...
path('api/token/verify/', TokenVerifyView.as_view(), name='token_verify'),
...
]
3、自定义令牌
通过继承TokenObtainPairSerializer类来自定义令牌
from rest_framework_simplejwt.serializers import TokenObtainPairSerializer
from rest_framework_simplejwt.views import TokenObtainPairView
class MyTokenObtainPairSerializer(TokenObtainPairSerializer):
@classmethod
def get_token(cls, user):
token = super().get_token(user)
# Add custom claims
token['name'] = user.name
# ...
return token
# Django project settings.py
...
SIMPLE_JWT = {
# It will work instead of the default serializer(TokenObtainPairSerializer).
"TOKEN_OBTAIN_SERIALIZER": "my_app.serializers.MyTokenObtainPairSerializer",
# ...
}
4、手动创建token
from rest_framework_simplejwt.tokens import RefreshToken
def get_tokens_for_user(user):
refresh = RefreshToken.for_user(user)
return {
'refresh': str(refresh),
'access': str(refresh.access_token),
}
评论区