注册

Django项目中使用JWT的实现代码

下面是关于Django项目中使用JWT的实现代码的完整攻略,包括最基本的JWT的使用和带有自定义用户模型的JWT使用:

基本JWT的使用

步骤1:安装相关库

在Django项目中使用JWT,需要安装两个Python库:pyjwtdjango-rest-framework-jwt,可以使用以下命令进行安装:

pip install pyjwt
pip install djangorestframework-jwt

步骤2:配置JWT

在Django项目的settings.py文件中添加如下配置:

REST_FRAMEWORK = {
    'DEFAULT_AUTHENTICATION_CLASSES': (
        'rest_framework_jwt.authentication.JSONWebTokenAuthentication',
    ),
}

JWT_AUTH = {
    'JWT_SECRET_KEY': '',
    'JWT_ALGORITHM': 'HS256',
    'JWT_ALLOW_REFRESH': True,
    'JWT_REFRESH_EXPIRATION_DELTA': datetime.timedelta(days=7),
    'JWT_EXPIRATION_DELTA': datetime.timedelta(hours=1),
}

其中,JWT_SECRET_KEY是自定义的JWT密钥,可以在环境变量中定义。

步骤3:用户认证

在Django项目中,可以使用DRF的TokenObtainPairView视图进行用户认证。假设我们的用户模型是Django自带的User模型,那么可以创建一个视图类继承自TokenObtainPairView,并指定用户模型为User,如下所示:

from rest_framework_simplejwt.views import TokenObtainPairView
from rest_framework_simplejwt.serializers import TokenObtainPairSerializer
from django.contrib.auth.models import User

class CustomTokenObtainPairSerializer(TokenObtainPairSerializer):
    @classmethod
    def get_user_model(cls):
        return User

    def validate(self, attrs):
        data = super().validate(attrs)
        data['username'] = self.user.username
        return data

class CustomTokenObtainPairView(TokenObtainPairView):
    serializer_class = CustomTokenObtainPairSerializer

这样,就可以在URL中使用CustomTokenObtainPairView.as_view()来进行用户认证,并获取JWT。

步骤4:JWT的使用

获取JWT之后,可以将JWT作为请求头中的Authorization字段,用于API调用上。例如,在Django视图中,可以使用如下方式获取JWT中的用户信息:

from rest_framework_jwt.authentication import JSONWebTokenAuthentication

class DemoView(APIView):
    authentication_classes = (JSONWebTokenAuthentication,)

    def get(self, request):
        user = request.user
        # do something

带有自定义用户模型的JWT使用

如果Django项目中使用的是自定义用户模型,那么需要对JWT进行相应的定制,以实现使用自定义用户模型的用户认证和获取JWT。以下是实现代码示例:

步骤1:安装相关库

安装django-allauthdjangorestframework-simplejwt,可以使用以下命令进行安装:

pip install django-allauth
pip install djangorestframework-simplejwt

步骤2:配置JWT

在Django项目的settings.py文件中添加如下配置:

AUTH_USER_MODEL = 'accounts.User'

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

SIMPLE_JWT = {
    'ACCESS_TOKEN_LIFETIME': timedelta(minutes=60),
    'REFRESH_TOKEN_LIFETIME': timedelta(days=7),
    'ROTATE_REFRESH_TOKENS': False,
    'JWT_SECRET_KEY': '',
    'JWT_ALGORITHM': 'HS256',
    'JWT_VERIFY': True,
    'JWT_VERIFY_EXPIRATION': True,
    'JWT_LEEWAY': 0,
    'JWT_EXPIRATION_DELTA': timedelta(minutes=60),
    'JWT_AUDIENCE': None,
    'JWT_ISSUER': None,
    'JWT_ALLOW_EXPIRED': False,
    'JWT_REFRESH_EXPIRATION_DELTA': timedelta(days=7),
    'JWT_AUTH_COOKIE': None,
}

其中,AUTH_USER_MODEL为自定义用户模型,JWT_SECRET_KEY是自定义的JWT密钥,可以在环境变量中定义。

步骤3:用户认证

在Django项目中,可以使用DRF的TokenObtainPairView视图进行用户认证。在自定义用户模型中,可以通过以下方式创建一个用户认证视图类:

from rest_framework.views import APIView
from rest_framework_simplejwt.views import TokenObtainPairView
from allauth.socialaccount.providers.weibo.views import WeiboOAuth2Adapter
from rest_auth.registration.views import SocialLoginView
from rest_auth.serializers import TokenSerializer
from rest_auth.views import LoginView
from django.contrib.auth import login
from django.shortcuts import redirect
from rest_framework_simplejwt.tokens import RefreshToken
import datetime

class CustomLoginView(LoginView):
    serializer_class = TokenSerializer

    def post(self, request, *args, **kwargs):
        serializer = self.get_serializer(data=request.data)
        if serializer.is_valid(raise_exception=True):
            time_delta = datetime.datetime.now() - datetime.datetime.fromtimestamp(
                request.META.get('HTTP_USER_AGENT'), datetime.datetime).replace(tzinfo=None)
            refresh = RefreshToken.for_user(serializer.validated_data['user'])

            if time_delta.days == 0 and time_delta.seconds < 1800:
                res = {"code": 200, "data": {"access_token": str(refresh.access_token)}, "msg": "OK"}
            else:
                res = {"code": 400, "msg": "验证码无效!"}

            login(request, serializer.validated_data['user'])

            response = Response(res)
            response.set_cookie(key='token', value=res.get('data').get('access_token'),
                                expires=refresh.access_token.payload.get('exp'), httponly=True)
            return response


class CustomTokenObtainPairView(TokenObtainPairView):
    serializer_class = CustomTokenObtainPairSerializer

在该视图类中,使用allauth库的WeiboOAuth2Adapter进行社交登录(这是示例代码,根据使用情况进行相应的修改),使用rest_auth库的SocialLoginView进行社交登录认证,在登录完成后,将JWT写入cookie中。

步骤4:JWT使用

在Django视图中,可以使用如下方式获取JWT中的用户信息:

from rest_framework_simplejwt.authentication import JWTAuthentication

class DemoView(APIView):
    authentication_classes = (JWTAuthentication,)

    def get(self, request):
        user = request.user
        # do something

以上是使用自定义用户模型的JWT使用的实现代码示例。