1. 安装 djangorestframework-jwt
pip install djangorestframework-jwt
  1. settings.py 中配置 JWT
INSTALLED_APPS = [
    # ...
    'rest_framework',
    'rest_framework_jwt',
    # ...
]

REST_FRAMEWORK = {
    'DEFAULT_AUTHENTICATION_CLASSES': [
        'rest_framework_jwt.authentication.JSONWebTokenAuthentication',
        # ...
    ],
}

JWT_AUTH = {
    'JWT_AUTH_HEADER_PREFIX': 'Bearer',
    'JWT_EXPIRATION_DELTA': datetime.timedelta(hours=4),
}

其中,JWT_EXPIRATION_DELTA 配置了 token 过期时间为 4 小时。

  1. 编写自定义验证方法

我们可以编写一个自定义的验证方法,在每个需要验证 token 的视图函数中使用。这个方法需要在 views.py 中定义。

from rest_framework_jwt.authentication import JSONWebTokenAuthentication
from rest_framework_jwt.utils import jwt_decode_handler

class CustomJSONWebTokenAuthentication(JSONWebTokenAuthentication):
    def authenticate(self, request):
        """
        Returns a two-tuple of `User` and token if a valid signature has been
        supplied using JWT-based authentication.  Otherwise returns `None`.
        """
        jwt_value = self.get_jwt_value(request)
        if jwt_value is None:
            return None

        try:
            payload = jwt_decode_handler(jwt_value)
            user = self.authenticate_credentials(payload)
            return (user, jwt_value)
        except:
            return None

    def authenticate_credentials(self, payload):
        """
        Returns an active user that matches the payload's user id and email.
        """
        user_id = payload.get('user_id')
        if not user_id:
            raise exceptions.AuthenticationFailed('Invalid payload.')

        try:
            user = User.objects.get(pk=user_id)
        except User.DoesNotExist:
            raise exceptions.AuthenticationFailed('User not found.')

        return user

这个方法继承了 JSONWebTokenAuthentication,并重写了其中的 authenticateauthenticate_credentials 方法。authenticate 方法中,我们通过 payload 判断 token 是否过期,如果过期则返回 Noneauthenticate_credentials 方法则处理验证 credentials 的逻辑。

  1. 在视图函数中使用自定义验证方法

在需要验证 token 的视图函数中,我们可以使用刚刚定义的自定义验证方法,如下所示:

from rest_framework.decorators import api_view, permission_classes
from rest_framework.permissions import IsAuthenticated
from rest_framework.response import Response
from rest_framework_jwt.settings import api_settings

@api_view(['GET'])
@permission_classes([IsAuthenticated])
def my_view(request):
    # do something
    return Response({'message': 'Hello, world!'})

其中,IsAuthenticated 表示需要验证 token,my_view 是视图函数名。这个视图函数只能在用户登录后才可以访问,否则会返回 401 错误


原文地址: https://www.cveoy.top/t/topic/hq3f 著作权归作者所有。请勿转载和采集!

免费AI点我,无需注册和登录