如何为Django视图的PUT/POST方法单独应用JWT认证,排除get_queryset?
解决Django视图中仅指定方法启用JWT认证的需求
你需要实现的是:让ProductList视图的post、put方法触发JWT认证,而get(对应get_queryset的查询请求)跳过认证,以下是两种可行方案:
方案一:重写视图的get_authenticators方法(推荐)
Django REST Framework的视图类提供get_authenticators方法,可动态返回当前请求的认证实例列表。通过重写该方法,根据HTTP方法判断是否启用认证:
class ProductList(generics.ListCreateAPIView): def get_queryset(self): # 原有查询逻辑 ... def post(self, request): # 原有创建逻辑 ... def put(self, request, *args, **kwargs): # 原有更新逻辑 ... def get_authenticators(self): # 仅POST/PUT请求启用JWT认证 if self.request.method in ('POST', 'PUT'): return [JWTAuthentication()] # GET请求不使用任何认证 return []
此方案将认证逻辑与视图绑定,灵活性更高,不会影响其他视图的认证规则。
方案二:在认证类中根据请求方法跳过认证
若不想修改视图方法,可在JWTAuthentication的authenticate方法中判断请求方法,GET请求直接跳过认证:
from rest_framework import exceptions, authentication from rest_framework.request import Request class JWTAuthentication(authentication.BaseAuthentication): def authenticate(self, request: Request): # GET请求直接跳过认证 if request.method == 'GET': return None print('authenticating') auth = authentication.get_authorization_header(request).split() print(auth) if auth and len(auth) == 2: token = auth[1].decode('utf-8') print('Decoded Token') print(token) id = decode_access_token(token) print(id) customer = models.Customer.objects.get(id=id) return (customer, None) raise exceptions.AuthenticationFailed('unauthenticated2')
注意:这种方式会让认证类与特定业务逻辑耦合,若其他视图需要GET请求认证,此方案不适用。
额外注意
如果视图设置了permission_classes,需确保GET请求允许匿名访问,比如添加:
def get_permissions(self): if self.request.method == 'GET': return [permissions.AllowAny()] return super().get_permissions()
内容的提问来源于stack exchange,提问作者user22257988
相关产品推荐
相关产品推荐

