Django:如何允许具有 AllowAny 权限的视图和方法绕过 HttpOnly JWT 令牌 cookie 的身份验证?

问题描述

我使用自定义中间件对 HttpOnly cookie 应用了 JWT 身份验证。现在,中间件会检查每个请求中是否存在 accessrefresh 令牌作为 HttpOnly cookie。一切正常。

但是,如果我请求不需要身份验证的页面,例如主页或博客列表或博客详细信息页面,它会返回 'KeyError': 'access'。如何在 access 设置为 permissions 的这些视图中以及仅将 AllowAny 方法权限设置为 {{1} 的某些视图中消除对 GET 令牌的这种需要}}?

我的观点:

AllowAny

如果请求方法class TagView(viewsets.ModelViewSet): queryset = Tag.objects.all() serializer_class = TagSerializer def get_permissions(self): if self.request.method == 'PUT': self.permission_classes = [permissions.IsAuthenticated,] elif self.request.method == 'GET': self.permission_classes = [permissions.AllowAny,] elif self.request.method == 'POST': self.permission_classes = [permissions.IsAuthenticated,] return super(TagView,self).get_permissions() ,即使没有找到GET cookie,中间件也应该传递请求。 现在,它会检查每个请求中的 access cookie。如果请求方法access 并且请求中没有 cookie,我添加了一行跳过请求令牌,将其标记GET 视图,但我认为这是不安全的。

我的中间件:

AllowAny

如果所选的 class AuthorizationHeaderMiddleware: def __init__(self,get_response=None): self.get_response = get_response def process_view(self,request,view_func,view_args,view_kwargs): pass def __call__(self,request): if request.path == '/api/auth/login/': return self.get_response(request) # for AllowAny views,I am doing this,but I think it is unsafe elif request.method == 'GET' and request.COOKIES == {}: # no cookies present return self.get_response(request) else: try: access_token = request.COOKIES['access'] key = settings.SECRET_KEY jwt.decode(access_token,key,algorithms=["HS256"]) request.Meta['HTTP_AUTHORIZATION'] = f'Bearer {access_token}' return self.get_response(request) except jwt.ExpiredSignatureError: refresh_cookie = request.COOKIES['refresh'] data = {"refresh": refresh_cookie} resp = requests.post('http://127.0.0.1:8000/api/auth/refresh/',data=data) access_token_string = json.loads(resp.text)["access"] request.Meta['HTTP_AUTHORIZATION'] = f'Bearer {access_token_string}' return self.get_response(request) 视图和方法没有 HttpOnly JWT 令牌 cookie,我如何允许它们?

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)