目录
1、安装依赖2、配置项目3、配置JWT3.1 配置默认认证类和权限类3.2 配置JWT设置4、创建视图和序列化器4.1创建自定义 Token 视图4.2 配置URL5、测试API5.1 注册新用户5.2 登录并获取JWT token5.3 刷新JWT token5.4 注销(将token加入黑名单)6、总结前言:JSON Web Tokens (JWT) 是一种开放标准 (RFC 7519),用于在各方之间安全地传输信息。在现代 Web 应用中,JWT 认证是一种常见的身份验证机制,它提供了无状态、轻量级的身份验证方式。本文将详细介绍如何在 Django REST Framework (DRF) 项目中实现 JWT 认证,并配置 token 黑名单以增强安全性。
1、安装依赖
需要安装 djangorestframework 和 djangorestframework-simplejwt 包。你可以使用 pip 来安装它们
pip install djangorestframeworkpip 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 timedeltaSIMPLE_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.pyfrom rest_framework_simplejwt.views import TokenObtainPairView, TokenRefreshView, TokenBlacklistViewfrom rest_framework_simplejwt.serializers import TokenObtainPairSerializerfrom rest_framework import statusfrom rest_framework.response import Responsefrom rest_framework.views import APIViewfrom django.contrib.auth.models import Userfrom .serializers import RegisterSerializerclass MyTokenObtainPairSerializer(TokenObtainPairSerializer): @classmethod def get_token(cls, user): token = super().get_token(user) # Add custom claims token['username'] = user.username return tokenclass MyTokenObtainPairView(TokenObtainPairView): serializer_class = MyTokenObtainPairSerializerclass 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.pyfrom rest_framework import serializersfrom django.contrib.auth.models import Userclass 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 userclass UserSerializer(serializers.ModelSerializer): class Meta: model = User fields = ('id', 'username', 'email')
4.2 配置URL
在 urls.py 中配置 URL 路由,以便访问登录、注册、刷新和注销视图:
# urls.pyfrom django.urls import pathfrom .views import MyTokenObtainPairView, RegisterViewurlpatterns = [ 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、总结
通过