DRF中djangorestframework-simplejwt认证前端无法正常工作求助
Django SimpleJWT 浏览器认证失败问题解决
我开发了一个包含注册、登录、用户信息接口的应用,Postman测试所有接口都正常返回结果,但使用djangorestframework-simplejwt做认证时,浏览器访问需要认证的接口返回401未授权错误,求解决。
相关配置与代码
settings.py 配置
from datetime import timedelta # JWT Configuration REST_FRAMEWORK = { 'DEFAULT_AUTHENTICATION_CLASSES': ( 'rest_framework_simplejwt.authentication.JWTAuthentication', ), } # JWT Settings SIMPLE_JWT = { 'ACCESS_TOKEN_LIFETIME': timedelta(minutes=20), 'REFRESH_TOKEN_LIFETIME': timedelta(days=1), 'AUTH_HEADER_TYPES': ('Bearer',), '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', } INSTALLED_APPS = [ # ... 其他应用 'rest_framework', 'rest_framework_simplejwt', # ... 其他应用 ]
登录视图(Views.py)
class UserLoginView(APIView): def post(self, request, format=None): q = QueryDict(request.body) query_dict = q.dict() json_object = json.dumps(query_dict, indent=4) reqBody = json.loads(json_object) email = reqBody['email'] password = reqBody['password'] user = authenticate(email=email, password=password) print('user') print(user) if user is not None: token = get_tokens_for_user(user) Account = customer.objects.get(email=email) request.session['email'] = Account.email request.session['id'] = Account.id request.session['name'] = Account.firstname request.session['cust_status'] = Account.cust_status request.session['os_name'] = Account.os_name request.session['user_type'] = Account.flag request.session['username'] = str(Account.firstname) + str(Account.lastname) return Response({'token': token, 'msg': 'Login Success'}, status=status.HTTP_200_OK) else: return Response({'errors': {'non_field_errors': ['Email or Password is not Valid']}}, status=status.HTTP_404_NOT_FOUND)
需要认证的测试API视图
@api_view(['GET']) @authentication_classes((TokenAuthentication,)) @permission_classes((IsAuthenticated,)) def test_view(request): return HttpResponse("Allowed")
错误信息
Test View GET /example_view HTTP 401 Unauthorized Allow: OPTIONS, GET Content-Type: application/json Vary: Accept WWW-Authenticate: Token { "detail": "Authentication credentials were not provided." }
问题原因及解决步骤
1. 认证类不匹配(核心问题)
全局配置使用的是JWTAuthentication,但测试视图硬编码了TokenAuthentication(这是DRF自带的Token认证,并非SimpleJWT的JWT认证逻辑),导致认证规则不兼容。
解决方法:
- 移除测试视图的
@authentication_classes((TokenAuthentication,))装饰器,直接使用全局配置的JWT认证:
@api_view(['GET']) @permission_classes((IsAuthenticated,)) def test_view(request): return HttpResponse("Allowed")
- 或者显式指定JWT认证类:
from rest_framework_simplejwt.authentication import JWTAuthentication @api_view(['GET']) @authentication_classes((JWTAuthentication,)) @permission_classes((IsAuthenticated,)) def test_view(request): return HttpResponse("Allowed")
2. 浏览器请求需正确携带Authorization头
浏览器请求时,必须在请求头中添加格式正确的认证信息:
Authorization: Bearer <你的access_token>
注意:Bearer与token之间有一个空格,access_token是登录接口返回的token.access字段值(登录接口返回的token是包含access和refresh的字典)。
3. 优化登录视图代码(可选)
登录视图中QueryDict转JSON的操作完全冗余,可直接用request.data获取参数;同时如果是纯API服务,无需操作session(JWT本身是无状态认证):
class UserLoginView(APIView): def post(self, request, format=None): email = request.data.get('email') password = request.data.get('password') user = authenticate(email=email, password=password) if user is not None: token = get_tokens_for_user(user) return Response({'token': token, 'msg': 'Login Success'}, status=status.HTTP_200_OK) else: return Response({'errors': {'non_field_errors': ['Email or Password is not Valid']}}, status=status.HTTP_401_UNAUTHORIZED)
内容的提问来源于stack exchange,提问作者Alam kazi
相关产品推荐
相关产品推荐

