djangorestframework-simplejwt使用

发布时间 2023-05-29 22:53:47作者: 哈哈哈哼

djangorestframework-simplejwt

环境

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)

安装

普通安装

pip3 install djangorestframework-jwt

加密安装

pip install djangorestframework-simplejwt[crypto]
#建议在使用 Simple JWT 的项目中使用 djangorestframework-simplejwt[crypto] 格式,以确保所有必要的依赖都被正确地安装和维护。

全局配置

REST_FRAMEWORK = {
    'DEFAULT_AUTHENTICATION_CLASSES': (
        'rest_framework_simplejwt.authentication.JWTAuthentication',
    )
}

需要在url中配置也达到刷新token

from rest_framework_simplejwt.views import (
    TokenObtainPairView,#获取token
    TokenRefreshView,#刷新token
)
urlpatterns = [
    path('api/token/', TokenObtainPairView.as_view()),
    path('api/token/refresh/', TokenRefreshView.as_view()),
]

如果需要做国际化,可以这样配置

INSTALLED_APPS = [
    'rest_framework_simplejwt',
]

LANGUAGE_CODE = 'en-us'

TIME_ZONE = 'UTC'

USE_I18N = True

USE_L10N = True

USE_TZ = True

用法

验证jwt是否正常引入

-X POST \
  -H "Content-Type: application/json" \
  -d '{"username": "davidattenborough", "password": "boatymcboatface"}' \
  http://localhost:8000/api/token/
{ "access":"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyX3BrIjoxLCJ0b2tlbl90eXBlIjoiYWNjZXNzIiwiY29sZF9zdHVmZiI6IuKYgyIsImV4cCI6MTIzNDU2LCJqdGkiOiJmZDJmOWQ1ZTFhN2M0MmU4OTQ5MzVlMzYyYmNhOGJjYSJ9.NHlztMGER7UADHZJlxNG0WSi22a2KaYSfd1S-AuT7lU",
  "refresh":"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyX3BrIjoxLCJ0b2tlbl90eXBlIjoicmVmcmVzaCIsImNvbGRfc3R1ZmYiOiLimIMiLCJleHAiOjIzNDU2NywianRpIjoiZGUxMmY0ZTY3MDY4NDI3ODg5ZjE1YWMyNzcwZGEwNTEifQ.aEoAYkSJjoWH1boshQAaTkf8G3yn0kapko6HFRt7Rh4"
}

settings配置

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),
}

自定义令牌

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)
        #get_token返回
        token['name'] = user.name
        return token
    
# Django project settings.py

SIMPLE_JWT = {
  "TOKEN_OBTAIN_SERIALIZER": "rest_framework_simplejwt.serializers.MyTokenObtainPairSerializer",
  # ...
}

手动创建令牌

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),
    }

token的类型

1  access #访问
2  sliding #滑动
3  refresh #刷新

sliding token(性能低)

from rest_framework_simplejwt.views import (
    TokenObtainSlidingView,
    TokenRefreshSlidingView,
)

urlpatterns = [
    path('api/token/', TokenObtainSlidingView.as_view(), name='token_obtain'),
    path('api/token/refresh/', TokenRefreshSlidingView.as_view(), name='token_refresh'),
]

Blacklist app

settings 配置

# Django project settings.py
INSTALLED_APPS = (
    'rest_framework_simplejwt.token_blacklist',
)

#创建 BlacklistMixin 子类实例并调用实例的黑名单方法将令牌列入黑名单:
from rest_framework_simplejwt.tokens import RefreshToken

token = RefreshToken(base64_encoded_token_string)
token.blacklist()

# url
from rest_framework_simplejwt.views import TokenBlacklistView

urlpatterns = [
  path('api/token/blacklist/', TokenBlacklistView.as_view(), name='token_blacklist'),
]

无状态用户身份验证

REST_FRAMEWORK = {
    'DEFAULT_AUTHENTICATION_CLASSES': (
        'rest_framework_simplejwt.authentication.JWTStatelessUserAuthentication',
    )
}
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)
        #get_token返回
        token['name'] = user.name
        return token
#get_token
@classmethod
def for_user(cls, user):
    token = super().for_user(user)
    jti = token[api_settings.JTI_CLAIM]
    exp = token["exp"]
    OutstandingToken.objects.create(
        user=user,
        jti=jti,
        token=str(token),
        created_at=token.current_time,
        expires_at=datetime_from_epoch(exp),
    )

    return token
#for_user
@classmethod
def for_user(cls, user):
    user_id = getattr(user, api_settings.USER_ID_FIELD)
    if not isinstance(user_id, int):
        user_id = str(user_id)
        token = cls()
        token[api_settings.USER_ID_CLAIM] = user_id
        return token
    _token_backend = None