发现了一篇很好的文章,上面说的很详细:
链接地址:Django REST Framework教程(7): 如何使用JWT认证(神文多图) - 知乎
或者如下步骤:
使用simplejwt:
1.安装:
pip install djangorestframework-simplejwt
2.配置
# settings.py
INSTALLED_APPS = [
...
'rest_framework',
'rest_framework_simplejwt',
]
REST_FRAMEWORK = {
'DEFAULT_PERMISSION_CLASSES': (
'rest_framework.permissions.IsAuthenticated',
),
# 认证类
# 先进行token的验证,如果没有携带token就进行session认证,如果没有session就就基本认证
# 认证顺序是从上到下,需要哪个加哪个
'DEFAULT_AUTHENTICATION_CLASSES': (
'rest_framework_simplejwt.authentication.JWTAuthentication',
'rest_framework.authentication.SessionAuthentication',
'rest_framework.authentication.BasicAuthentication',
),
}
SIMPLE_JWT = {
# token有效时长(返回的 access 有效时长)
'ACCESS_TOKEN_LIFETIME': datetime.timedelta(seconds=30),
# token刷新的有效时间(返回的 refresh 有效时长)
'REFRESH_TOKEN_LIFETIME': datetime.timedelta(seconds=20),
}
3.url.py
from rest_framework_simplejwt.views import TokenObtainPairView, TokenRefreshView, TokenVerifyView
urlpatterns = [
# 登录接口
path('authorizations/', TokenObtainPairView.as_view(), name='token_obtain_pair'),
# 刷新token
path('refresh/', TokenRefreshView.as_view(), name='token_refresh'),
# 校验token
path('verify/', TokenVerifyView.as_view(), name='token_verify'),
]
4.其他设置
# Django project settings.py
from datetime import timedelta
...
SIMPLE_JWT = {
"ACCESS_TOKEN_LIFETIME": timedelta(minutes=5),
"REFRESH_TOKEN_LIFETIME": timedelta(days=1),
"ROTATE_REFRESH_TOKENS": False,
"BLACKLIST_AFTER_ROTATION": False,
"UPDATE_LAST_LOGIN": False,
"ALGORITHM": "HS256",
"SIGNING_KEY": settings.SECRET_KEY,
"VERIFYING_KEY": "",
"AUDIENCE": None,
"ISSUER": None,
"JSON_ENCODER": None,
"JWK_URL": None,
"LEEWAY": 0,
"AUTH_HEADER_TYPES": ("Bearer",),
"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),
"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",
}
ACCESS_TOKEN_LIFETIME
datetime.timedelta指定访问令牌有效时间的对象。该timedelta值在令牌生成期间添加到当前 UTC 时间以获得令牌的默认“exp”声明值。
REFRESH_TOKEN_LIFETIME
datetime.timedelta指定刷新令牌有效时间的对象。该timedelta值在令牌生成期间添加到当前 UTC 时间以获得令牌的默认“exp”声明值。
ROTATE_REFRESH_TOKENS
设置为 时True,如果将刷新令牌提交给 TokenRefreshView,则新的刷新令牌将与新的访问令牌一起返回。这个新的刷新令牌将通过 JSON 响应中的“刷新”键提供。新的刷新令牌将有一个更新的到期时间,该时间是通过将设置中的 timedelta 添加REFRESH_TOKEN_LIFETIME 到发出请求时的当前时间来确定的。如果黑名单应用程序正在使用中并且BLACKLIST_AFTER_ROTATION设置为True,则提交到刷新视图的刷新令牌将被添加到黑名单中。
BLACKLIST_AFTER_ROTATION
设置为 时,如果黑名单应用程序正在使用且设置设置True为 ,则提交给 的刷新令牌 将被添加到黑名单。您需要在设置文件中添加才能使用此设置。 TokenRefreshViewROTATE_REFRESH_TOKENSTrue’rest_framework_simplejwt.token_blacklist’,INSTALLED_APPS
注:原文链接:DRF 使用djangorestframework-jwt 报错_名难取aaa的博客-CSDN博客
5、 定制化jwt,可以将用户信息存入token中,也可以将用户信息从接口中返回
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(MyTokenObtainPairSerializer, cls).get_token(user)
# Add custom claims
token['username'] = user.username
token['password'] = user.password
return token
def validate(self, attrs):
data = super().validate(attrs)
# 获取Token对象
refresh = self.get_token(self.user)
# 加个token的键,值和access键一样
data['token'] = data['access']
# 然后把access键干掉
del data['access']
# 令牌到期时间
data['expire'] = refresh.access_token.payload['exp'] # 有效期
# 用户名
data['username'] = self.user.username
# 邮箱
data['id'] = self.user.id
return data
class MyObtainTokenPairView(TokenObtainPairView):
serializer_class = MyTokenObtainPairSerializer
然后将url中的类替换为MyObtainTokenPairView即可
返回结果:
解密jwt结果: