如何在Django Rest框架中使用仅HTTP Cookie?

问题描述

我阅读了一些与在本地存储中存储jwt令牌相关的问题,这就是为什么我试图将令牌存储在仅HTTP cookie中的原因。我正在使用以下方法

from rest_framework.views import APIView
from rest_framework.response import Response
import jwt
from django.conf import settings
from rest_framework import status

class LoginView(APIView):
    def post(self,request,format=None):
        email = request.data['email']
        password = request.data['password']

        # dummy user authentication
        if email == 'email' and password == 'password':
            encoded = jwt.encode(
                {'email': email},settings.SECRET_KEY,algorithm='HS256')

            response = Response()
            response.set_cookie(key='token',value=encoded,httponly=True)
            response.data = {
                'user': email,}
            return response
        else:
            return Response({'error': 'wrong credentials'},status=status.HTTP_401_UNAUTHORIZED)

问题1:使用django rest框架设置httponly cookie的方法正确吗?

response = Response()
response.set_cookie(key='token',httponly=True)
response.data = {
    'user': email,}
return response

此后,每次我从客户端收到请求(使用React与axios结合使用)时,我都可以在django视图中使用request.COOKIES['token']访问cookie。使用此代码,我可以编写自己的身份验证功能,但我认为这不是一种完美的方法,因为通常,我们在授权标头中传递令牌,该标头基于令牌设置request.user,如果使用此方法,我会不能使用邮递员进行测试,而django rest框架IsAuthenticated类也会寻找request.user and request.user.is_authenticated的True值。

问题2:如果令牌存储在httponly cookie中,如何将令牌作为客户端的授权标头传递?

请帮助我。我对仅使用HTTP的cookie的工作流程有些困惑,因为通常我以前将令牌存储在本地存储中,并且检索令牌并将其从前端传递更容易。

解决方法

答案 1:

是的,这是设置 httponly 标志 cookie 的好方法,因为 httpOnly 无法访问 JavaScript cookie。 如果没有 httponly 标志 cookie,它容易受到 CSRF 攻击。

虽然 localStorage 可通过 javascript(而不是 HttpOnly cookie)访问,并使其容易受到 XSS 攻击。 所以我认为使用 httponly cookies + CSRF 是最安全的方式,即使在 TokenAuthentication 中用于在客户端存储令牌。但是,DRF 和我看过的其他流行库并没有很好地支持这一点。

答案 2:

不,因为你不能从客户端使用 httponly 来检索 javascript cookie。这是 httponly cookie 的一大优势。所以这个 cookie 只能通过 http(s) 请求访问. 确保两边的 withCredentials 都是 True

我个人使用 djangorestframework-simplejwt 包在 access token cookie 中设置(CSRF + httponly 令牌)并使用 CustomAuthentication 类获取。 Check this