【django】Django REST Framework (DRF) 项目中实现 JWT

目录

1、安装依赖

2、配置项目

3、配置JWT

[3.1 配置默认认证类和权限类](#3.1 配置默认认证类和权限类)

[3.2 配置JWT设置](#3.2 配置JWT设置)

4、创建视图和序列化器

[4.1 创建自定义 Token 视图](#4.1 创建自定义 Token 视图)

[4.2 配置URL](#4.2 配置URL)

5、测试API

[5.1 注册新用户](#5.1 注册新用户)

[5.2 登录并获取JWT token](#5.2 登录并获取JWT token)

[5.3 刷新JWT token](#5.3 刷新JWT token)

[5.4 注销(将token加入黑名单)](#5.4 注销(将token加入黑名单))

6、总结


前言:JSON Web Tokens (JWT) 是一种开放标准 (RFC 7519),用于在各方之间安全地传输信息。在现代 Web 应用中,JWT 认证是一种常见的身份验证机制,它提供了无状态、轻量级的身份验证方式。本文将详细介绍如何在 Django REST Framework (DRF) 项目中实现 JWT 认证,并配置 token 黑名单以增强安全性。

1、安装依赖

需要安装 djangorestframework 和 djangorestframework-simplejwt 包。你可以使用 pip 来安装它们

复制代码
pip install djangorestframework
pip install djangorestframework-simplejwt

2、配置项目

编辑 settings.py 文件,添加 rest_framework 和 rest_framework_simplejwt 到 INSTALLED_APPS:

复制代码
INSTALLED_APPS = [
    ...
    'rest_framework',
    'rest_framework_simplejwt',
    'rest_framework_simplejwt.token_blacklist',
    ...
]

3、配置JWT

3.1 配置默认认证类和权限类

在 settings.py 中配置默认的认证类和权限类:

复制代码
REST_FRAMEWORK = {
    'DEFAULT_AUTHENTICATION_CLASSES': (
        'rest_framework_simplejwt.authentication.JWTAuthentication',
    ),
    'DEFAULT_PERMISSION_CLASSES': (
        'rest_framework.permissions.IsAuthenticated',
    ),
}

3.2 配置JWT设置

在 settings.py 中配置 JWT 的一些选项,例如 token 的过期时间、签名算法等:

复制代码
from datetime import timedelta

SIMPLE_JWT = {
    'ACCESS_TOKEN_LIFETIME': timedelta(minutes=5),
    'REFRESH_TOKEN_LIFETIME': timedelta(days=1),
    'ROTATE_REFRESH_TOKENS': True,
    'BLACKLIST_AFTER_ROTATION': True,
    'ALGORITHM': 'HS256',
    'SIGNING_KEY': SECRET_KEY,
    'VERIFYING_KEY': None,
    'AUTH_HEADER_TYPES': ('Bearer',),
    'USER_ID_FIELD': 'id',
    'USER_ID_CLAIM': 'user_id',
    'AUTH_TOKEN_CLASSES': ('rest_framework_simplejwt.tokens.AccessToken',),
    'TOKEN_TYPE_CLAIM': 'token_type',
}

4、创建视图和序列化器

4.1 创建自定义 Token 视图

创建一个视图来处理登录请求,返回 JWT token。

复制代码
# views.py
from rest_framework_simplejwt.views import TokenObtainPairView, TokenRefreshView, TokenBlacklistView
from rest_framework_simplejwt.serializers import TokenObtainPairSerializer
from rest_framework import status
from rest_framework.response import Response
from rest_framework.views import APIView
from django.contrib.auth.models import User
from .serializers import RegisterSerializer

class MyTokenObtainPairSerializer(TokenObtainPairSerializer):
    @classmethod
    def get_token(cls, user):
        token = super().get_token(user)
        # Add custom claims
        token['username'] = user.username
        return token

class MyTokenObtainPairView(TokenObtainPairView):
    serializer_class = MyTokenObtainPairSerializer

class RegisterView(APIView):
    def post(self, request, *args, **kwargs):
        serializer = RegisterSerializer(data=request.data)
        if serializer.is_valid():
            user = serializer.save()
            return Response({
                "user": UserSerializer(user, context=self.get_serializer_context()).data,
                "message": "User Created Successfully.  Now perform Login to get your token",
            })
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

# serializers.py
from rest_framework import serializers
from django.contrib.auth.models import User

class RegisterSerializer(serializers.ModelSerializer):
    class Meta:
        model = User
        fields = ('username', 'password', 'email')
        extra_kwargs = {'password': {'write_only': True}}

    def create(self, validated_data):
        user = User.objects.create_user(
            username=validated_data['username'],
            email=validated_data['email'],
            password=validated_data['password']
        )
        return user

class UserSerializer(serializers.ModelSerializer):
    class Meta:
        model = User
        fields = ('id', 'username', 'email')

4.2 配置URL

在 urls.py 中配置 URL 路由,以便访问登录、注册、刷新和注销视图:

复制代码
# urls.py
from django.urls import path
from .views import MyTokenObtainPairView, RegisterView

urlpatterns = [
    path('login/', MyTokenObtainPairView.as_view(), name='token_obtain_pair'),
    path('login/refresh/', TokenRefreshView.as_view(), name='token_refresh'),
    path('logout/', TokenBlacklistView.as_view(), name='token_blacklist'),
    path('register/', RegisterView.as_view(), name='auth_register'),
]

5、测试API

使用 Postman 或其他 HTTP 客户端来测试你的 API。以下是一些示例请求:

5.1 注册新用户

URL: /register/

Method: POST

Body:

复制代码
{
  "username": "testuser",
  "email": "testuser@example.com",
  "password": "testpassword"
}

5.2 登录并获取JWT token

URL: /login/

Method: POST

Body:

复制代码
{
  "username": "testuser",
  "password": "testpassword"
}

5.3 刷新JWT token

URL: /login/refresh/

Method: POST

Body:

复制代码
{
  "refresh": "your_refresh_token"
}

5.4 注销(将token加入黑名单)

URL: /logout/

Method: POST

Body:

复制代码
{
  "refresh": "your_refresh_token"
}

6、总结

通过以上步骤,我们成功地在 Django REST Framework 项目中实现了 JWT 认证,并配置了 token 黑名单以增强安全性。JWT 认证提供了一种无状态、轻量级的身份验证方式,而 token 黑名单则确保了已注销的 token 不会被再次使用,从而提高了应用的安全性。

希望这篇文章对你有所帮助!如果你有任何问题或需要进一步的帮助,请随时联系我。

相关推荐
郭小李15 分钟前
spring 的 @CookieValue 注解 用法
java·后端·spring
Metaphor69236 分钟前
轻松使用 Python 将 RTF 转换为 Word(含批量转换与格式互转)
python·word·rtf
zh路西法36 分钟前
【深入理解 LSTM】从时间反向传播(BPTT)到长时记忆:门控机制与实验验证
pytorch·python·rnn·gru·lstm·bptt
青少儿编程课堂39 分钟前
蓝桥杯青少组 + 全国青少年信息素养大赛 + 电子学会图形化考级|校园推箱子大挑战解析
c++·python·算法·bfs·信息学竞赛
god_cvz41 分钟前
麒麟 V10(ARM64 / aarch64)源码编译 3dtiles 全步骤
后端·gis
武子康43 分钟前
批量设备任务显示 COMPLETED,为什么还有设备失败?
人工智能·后端·agent
2601_9669496543 分钟前
Python 实战:如何统计五档盘口买卖盘总挂单量?附计算公式与代码
开发语言·python·数据分析·pandas·量化交易·股票数据·quantdash
泡海椒1 小时前
折线图Y轴刻度悬空之谜-信用评级趋势
后端
.Bryce.1 小时前
T2-LLM评测不等于Agent评测
android·java·人工智能·后端·gpt·agent·1024程序员节
全栈陈序员1 小时前
【Python】基础语法入门(二十九)—— 正则表达式实战:文本处理利器
开发语言·人工智能·python·正则表达式