Django REST API中使用Token认证获取信息时的问题
Django REST API Token认证获取数据失败问题
执行GET/POST请求时触发认证错误:
{"detail": "Authentication credentials were not provided."}
我的代码
views.py
from django.shortcuts import render from rest_framework.views import APIView from rest_framework.response import Response from .models import Student from .serlizer import StudentSerlilizer from rest_framework import status from rest_framework.authentication import TokenAuthentication from rest_framework.permissions import IsAuthenticated class StudentInfo(APIView): authentication_classes = [TokenAuthentication] # 应用Token认证 permission_classes = [IsAuthenticated] # 仅允许已认证用户访问 def get(self, request, format=None): stu = Student.objects.all() serlizer = StudentSerlilizer(stu, many=True) return Response(serlizer.data) def post(self, request, format=None): request_data = request.data serlizer = StudentSerlilizer(data=request_data) if serlizer.is_valid(): serlizer.save() msg = {'msg':'数据已保存'} return Response(msg) msg = {'msg': serlizer.errors} return Response(msg, status.HTTP_400_BAD_REQUEST)
urls.py
from django.urls import path from . import views # from rest_framework.authtoken.views import obtain_auth_token from rest_framework_simplejwt.views import TokenObtainPairView, TokenRefreshView, TokenVerifyView urlpatterns = [ # path('authtoken/',obtain_auth_token), path('gettoken/', TokenObtainPairView.as_view(), name="get_token"), path('refreshtoken/', TokenRefreshView.as_view(), name="refresh_token"), path('verifytoken/', TokenVerifyView.as_view(), name="verify_token"), path('studentinfo/', views.StudentInfo.as_view(), name="studentlist"), path('studentinfo/<int:pk>/', views.StudentRUD.as_view(), name="StudentRUD") ]
请求示例及错误响应
http GET http://127.0.0.1:8000/studentinfo/ 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ0b2tlbl90eXBlIjoiYWNjZXNzIiwiZXhwIjoxNjk1MzYxMTk5LCJpYXQiOjE2OTUzNjA4OTksImp0aSI6ImY1ODY1MWE5NjMwNTRhMDA4MzA6NTFmZTJmMzU1MTgwIiwidXNlcl9pZCI6MX0.GmlHfKR59s6SUDEI_ZHardNDDH7T_lEWYJlIBxc3LmI' HTTP/1.1 401 Unauthorized Allow: GET, POST, HEAD, OPTIONS Content-Length: 58 Content-Type: application/json Cross-Origin-Opener-Policy: same-origin Date: Fri, 22 Sep 2023 05:46:15 GMT Referrer-Policy: same-origin Server: WSGIServer/0.2 CPython/3.10.11 Vary: Accept WWW-Authenticate: Token X-Content-Type-Options: nosniff X-Frame-Options: DENY { "detail": "Authentication credentials were not provided." }
问题原因及解决方法
核心原因
你用simplejwt生成的Bearer Token发起请求,但视图配置的是DRF自带的TokenAuthentication——这两套认证系统不兼容:
- DRF自带
TokenAuthentication只识别Authorization: Token <token值>格式的请求头 - simplejwt生成的Token需要用
JWTAuthentication类,且请求头格式为Authorization: Bearer <token值>
方案一:改用DRF原生Token系统
- 恢复urls中DRF原生Token路由,注释掉simplejwt相关路由:
path('authtoken/', obtain_auth_token), # path('gettoken/', TokenObtainPairView.as_view(), name="get_token"), # path('refreshtoken/', TokenRefreshView.as_view(), name="refresh_token"), # path('verifytoken/', TokenVerifyView.as_view(), name="verify_token"),
- 在settings.py中添加DRF Token应用:
INSTALLED_APPS = [ # ...其他应用 'rest_framework.authtoken', ]
- 为用户生成Token:
- 命令行执行:
python manage.py drf_create_token <用户名> - 或通过Django后台手动生成
- 命令行执行:
- 请求时使用正确的头格式:
http GET http://127.0.0.1:8000/studentinfo/ 'Authorization: Token <你的原生Token值>'
方案二:继续使用simplejwt,替换认证类
- 视图中替换认证类为JWTAuthentication:
from rest_framework_simplejwt.authentication import JWTAuthentication class StudentInfo(APIView): authentication_classes = [JWTAuthentication] # 替换为JWT认证类 permission_classes = [IsAuthenticated] # ...其余代码不变
- (可选)全局配置JWT认证(无需每个视图单独设置):
在settings.py中添加:
REST_FRAMEWORK = { 'DEFAULT_AUTHENTICATION_CLASSES': [ 'rest_framework_simplejwt.authentication.JWTAuthentication', ], }
内容的提问来源于stack exchange,提问作者Mohit Mishra
相关产品推荐
相关产品推荐

