带有 cookie 的 django-rest-knox

IT技术 reactjs django-rest-framework
2021-05-07 08:13:24

我有一个关于使用 django-rest-knox 进行身份验证的问题。我想在客户端使用 cookie 存储,而不是 localStorage。所以我要实现如下


class LoginView(GenericAPIView):
    serializer_class = LoginSerializer
    permission_classes = (AllowAny,)

    def post(self, request, *args, **kwargs):
        serializer = self.get_serializer(data=request.data)
        serializer.is_valid(raise_exception=True)
        user = serializer.validated_data
        token = AuthToken.objects.create(user)
        response = Response({
            'user': UserSerializer(user, context=self.get_serializer_context()).data,
            'token': token
        })
        response.set_cookie('token',
                            token,
                            httponly=True)
        return response

使用 django-rest-knox 是正确的方法吗?或者我需要使用localStorage吗?我不想使用 JWT,因为我在这里看到了很多负面意见。

1个回答

首先,感谢您发布这个问题。我有一个类似的要求,即不使用本地存储,并且您的工作指向了正确的方向。

看看 Knox 的LoginView实现(这里),看起来有相当数量的逻辑没有在您的版本中复制(例如,令牌计数限制)。

我采取了扩展 Knox 的LoginView. 我调用默认post方法来使用 Knox 的实现,然后去掉我不想让客户端上的 JS 可用的信息。

from django.contrib.auth import login
from rest_framework import permissions
from rest_framework.authtoken.serializers import AuthTokenSerializer
from knox.views import LoginView as KnoxLoginView


class LoginView(KnoxLoginView):
    permission_classes = (permissions.AllowAny,)

    def post(self, request, format=None):
        serializer = AuthTokenSerializer(data=request.data)
        serializer.is_valid(raise_exception=True)
        user = serializer.validated_data['user']
        login(request, user)
        response = super(LoginView, self).post(request, format=None)

        token = response.data['token']
        del response.data['token']

        response.set_cookie(
            'auth_token',
            token,
            httponly=True,
            samesite='strict'
        )

        return response