如何使用Django Rest Framework正确设置令牌认证?

时间:2016-09-04 19:23:48

标签: django python-3.x authentication django-rest-framework django-rest-auth

我正在使用DRF 1.10和Python 3.5。

我正在尝试使用DRF' rest_framework.authtoken.models.Token来验证用户的登录信息。这就是我所拥有的:

views.py

class LoginView(views.APIView):
    serializer_class = LoginSerializer

    def post(self, request, **kwargs):
        serializer = self.serializer_class(data=request.data)
        if serializer.is_valid():
            user = User.objects.get(username=serializer.data['username'])
            token = Token.objects.create(user=user)

            response = {}
            response['user'] = serializer.data
            response['token'] = token.key

            return Response(response, status=status.HTTP_200_OK)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

serializers.py

class LoginSerializer(serializers.Serializer):
    username = serializers.CharField()
    password = serializers.CharField()

    def validate(self, attrs):
        username = attrs.get("username").lower()
        password = attrs.get("password")

        user = authenticate(username=username, password=password)

        if user:
            attrs["user"] = user
            return attrs
        else:
            raise serializers.ValidationError(
                "Unable to login with credentials provided."
            )

登录时我想为用户提供一个令牌,在注销时我想删除该令牌。问题是,当我尝试通过使用令牌密钥和与之相关的用户查找令牌来删除令牌时,我无法找到令牌。注销视图在这里:

class LogoutView(views.APIView):
    def post(self, request, **kwargs):
        try:
            token = request.META['HTTP_AUTHORIZATION'].split(" ")[1]
            invalidate_token = Token.objects.filter(key=token, user=request.user)
            invalidate_token.delete()

        return Response({ detail: "Logged out"}, status=status.HTTP_202_ACCEPTED)
    except:
        return Response({"error": ["Token does not exist!"]}, status=status.HTTP_400_BAD_REQUEST)

当我尝试将用户注销时,我遇到了问题。我意识到request.user仍然是AnonymousUser而不是User。我该如何解决这个问题?

Header from Postman

这是邮递员的标题。

1 个答案:

答案 0 :(得分:0)

因为Token是无状态的,所以与标准的Django会话认证不同,你应该将该令牌放在所有请求中。
出于测试目的,您可以安装一些chrome插件来修改授权标头,例如modheader
把它放在标题中:

Authorization: Token <your_toke_string>  

用户将通过身份验证