djangorestframework-simplejwt教程及使用

宗安翔
2023-12-01

一、说明

  1. 适用版本(

    • Python (3.7, 3.8, 3.9, 3.10)
    • Django (2.2, 3.1, 3.2, 4.0)
    • Django REST Framework (3.10, 3.11, 3.12, 3.13)

  2. 功能

  3. 安装

  4. 配置

  5. 在视图中使用

二、功能

simplejwt是Django REST Framework的 JSON Web Token 身份验证插件。 提供 JSON Web Token 身份验证后端。

三、安装

  1. 安装
pip install djangorestframework-simplejwt

四、项目配置(全局配置)

  1. 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"
}
  1. 其它设置
# 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 . 自定义令牌声明

如果您希望自定义由TokenObtainPairViewTokenObtainSlidingView视图生成的 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 路由。

  1. 自定义登录
    可能有时候你需要的不仅仅是通过用户名登录,还可以通过手机邮箱等其他用户信息
    views.py
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'),
]
 类似资料: