Django视图配置疑问:GET无需Token但POST需Token的实现问题
问题解决:Django DRF视图GET请求无需Token,POST需Token验证
问题根源
你设置了JWTAuthentication作为视图的全局认证类,DRF会对**所有请求(包括GET)**执行token认证流程。即使配置了IsAuthenticatedOrReadOnly权限类,认证环节如果检测不到合法token就会直接返回401错误,根本走不到权限校验的步骤。
解决方案
方案1:重写视图的get_authenticators方法
直接根据请求方法动态返回认证器,仅POST请求启用JWT认证:
from rest_framework.views import Request, Response, status, APIView from .serializers import MovieSerializer from rest_framework_simplejwt.authentication import JWTAuthentication from rest_framework.permissions import IsAuthenticatedOrReadOnly from movies.models import Movie class MovieView(APIView): permission_classes = [IsAuthenticatedOrReadOnly] def get_authenticators(self): # 仅POST请求使用JWT认证 if self.request.method == 'POST': return [JWTAuthentication()] # GET请求不启用任何认证器 return [] def post(self, request: Request) -> Response: serializer = MovieSerializer(data=request.data) serializer.is_valid(raise_exception=True) serializer.save(user=request.user) return Response(serializer.data, status=status.HTTP_201_CREATED) def get(self, request: Request) -> Response: movies = Movie.objects.all() serializer = MovieSerializer(movies, many=True) return Response(serializer.data, status=status.HTTP_200_OK)
方案2:自定义可选JWT认证类
创建一个自定义认证类,根据请求方法决定是否强制校验token:
from rest_framework_simplejwt.authentication import JWTAuthentication class OptionalJWTAuthentication(JWTAuthentication): def authenticate(self, request): # GET请求直接跳过认证,返回None表示匿名用户 if request.method == 'GET': return None # 其他请求正常执行JWT认证逻辑 return super().authenticate(request)
然后在视图中使用这个自定义认证类:
class MovieView(APIView): authentication_classes = [OptionalJWTAuthentication] permission_classes = [IsAuthenticatedOrReadOnly] # 后续post、get方法保持不变
原理说明
DRF的请求处理流程是:认证(Authentication)→ 权限(Permissions)→ 节流(Throttling)。只有认证环节通过(或允许匿名),才会进入权限校验。IsAuthenticatedOrReadOnly的作用是:允许认证用户执行任何操作,匿名用户仅允许只读操作,但前提是认证环节没有抛出错误。
内容的提问来源于stack exchange,提问作者NewDev
相关产品推荐
相关产品推荐

