适用版本(
)
功能
安装
配置
在视图中使用
simplejwt是Django REST Framework的 JSON Web Token 身份验证插件。 提供 JSON Web Token 身份验证后端。
pip install djangorestframework-simplejwt
然后,您的 django 项目必须配置为使用该库。在 settings.py
中,添加 rest_framework_simplejwt.authentication.JWTAuthentication
到身份验证类列表:
REST_FRAMEWORK = {
...
'DEFAULT_AUTHENTICATION_CLASSES': (
...
'rest_framework_simplejwt.authentication.JWTAuthentication',
)
...
}
curl \
-X POST \
-H "Content-Type: application/json" \
-d '{"username": "davidattenborough", "password": "boatymcboatface"}' \
//查看token地址
http://localhost:8000/api/token/
...
{
"access":"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyX3BrIjoxLCJ0b2tlbl90eXBlIjoiYWNjZXNzIiwiY29sZF9zdHVmZiI6IuKYgyIsImV4cCI6MTIzNDU2LCJqdGkiOiJmZDJmOWQ1ZTFhN2M0MmU4OTQ5MzVlMzYyYmNhOGJjYSJ9.NHlztMGER7UADHZJlxNG0WSi22a2KaYSfd1S-AuT7lU",
"refresh":"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyX3BrIjoxLCJ0b2tlbl90eXBlIjoicmVmcmVzaCIsImNvbGRfc3R1ZmYiOiLimIMiLCJleHAiOjIzNDU2NywianRpIjoiZGUxMmY0ZTY3MDY4NDI3ODg5ZjE1YWMyNzcwZGEwNTEifQ.aEoAYkSJjoWH1boshQAaTkf8G3yn0kapko6HFRt7Rh4"
}
# Django project settings.py
from datetime import timedelta
...
SIMPLE_JWT = {
'ACCESS_TOKEN_LIFETIME': timedelta(minutes=5),
# 设置token过期时间,上面是5分钟
'REFRESH_TOKEN_LIFETIME': timedelta(days=1),
# 设置token刷新过期时间,上面是1天
'ROTATE_REFRESH_TOKENS': False,
#
'BLACKLIST_AFTER_ROTATION': False,
#黑名单应用程序【https://django-rest-framework-simplejwt.readthedocs.io/en/latest/blacklist_app.html】
'UPDATE_LAST_LOGIN': False,
#当设置为 时True,auth_user 表中的 last_login 字段在登录时更新 (TokenObtainPairView)。
#会更新刷新token
'ALGORITHM': 'HS256',
#解码方式hs256
'SIGNING_KEY': SECRET_KEY,
'VERIFYING_KEY': None,
'AUDIENCE': None,
'ISSUER': None,
'JWK_URL': None,
'LEEWAY': 0,
'AUTH_HEADER_TYPES': ('Bearer',),
#请求头中协带Authorization: Bearer <token>
'AUTH_HEADER_NAME': 'HTTP_AUTHORIZATION',
'USER_ID_FIELD': 'id',
'USER_ID_CLAIM': 'user_id',
'USER_AUTHENTICATION_RULE': 'rest_framework_simplejwt.authentication.default_user_authentication_rule',
'AUTH_TOKEN_CLASSES': ('rest_framework_simplejwt.tokens.AccessToken',),
'TOKEN_TYPE_CLAIM': 'token_type',
'TOKEN_USER_CLASS': 'rest_framework_simplejwt.models.TokenUser',
'JTI_CLAIM': 'jti',
'SLIDING_TOKEN_REFRESH_EXP_CLAIM': 'refresh_exp',
'SLIDING_TOKEN_LIFETIME': timedelta(minutes=5),
'SLIDING_TOKEN_REFRESH_LIFETIME': timedelta(days=1),
}
3 . 自定义令牌声明
如果您希望自定义由TokenObtainPairView
和TokenObtainSlidingView
视图生成的 Web 令牌中包含的声明,请为所需视图创建一个子类,并为其相应的序列化程序创建一个子类。以下是如何自定义生成的令牌中的声明的示例TokenObtainPairView
:
from rest_framework_simplejwt.serializers import TokenObtainPairSerializer
from rest_framework_simplejwt.views import TokenObtainPairView
#可以改变token的值,token加密
class MyTokenObtainPairSerializer(TokenObtainPairSerializer):
@classmethod
def get_token(cls, user):
token = super().get_token(user)
# Add custom claims
token['name'] = user.name
# ...
return token
#返回数据
def validate(self, attrs):
data = super().validate(attrs)
refresh = self.get_token(self.user)
data['refresh'] = str(refresh)
data['access'] = str(refresh.access_token)
data['username'] = 'hrj'
return data
class MyTokenObtainPairView(TokenObtainPairView):
serializer_class = MyTokenObtainPairSerializer
请注意,上面的示例将导致自定义声明出现在视图生成的刷新和访问令牌中。这是因为get_token
上面的方法为视图生成了刷新令牌,而刷新令牌又用于生成视图的访问令牌。
与标准令牌视图一样,您还需要包含指向子类视图的 url 路由。
from django.contrib.auth.backends import ModelBackend
from django.db.models import Q
# 记得引入用户的model
class CustomBackend(ModelBackend):
def authenticate(self, request, username=None, password=None, **kwargs):
# noinspection PyBroadException
try:
# 小编这里添加了一个手机验证,如果需要其他验证再加就ok了
user = UserProfile.objects.get(Q(username=username) | Q(mobile=username))
if user.check_password(password):
return user
except Exception as e:
return None
上面的修改完后你还需要将修改后的类配置到setting.py中
AUTHENTICATION_BACKENDS = (
'users.views.CustomBackend',
)
这里直接编写项目下的根路由文件
from django.urls import path, include
# 导入 simplejwt 提供的几个验证视图类
from rest_framework_simplejwt.views import (
TokenObtainPairView,
TokenRefreshView,
TokenVerifyView
)
urlpatterns = [
# DRF 提供的一系列身份认证的接口,用于在页面中认证身份,详情查阅DRF文档
path('api-auth/', include('rest_framework.urls', namespace='rest_framework')),
# 获取Token的接口
path('api/token/', TokenObtainPairView.as_view(), name='token_obtain_pair'),
# 刷新Token有效期的接口
path('api/refresh/', TokenRefreshView.as_view(), name='token_refresh'),
# 验证Token的有效性
path('api/token/verify/', TokenVerifyView.as_view(), name='token_verify'),
]