【问题标题】:Logout in Django Rest Framework在 Django Rest 框架中注销
【发布时间】:2019-10-07 13:37:03
【问题描述】:

未能实现用户logout

这里是代码。我正在尝试从命令行运行 curl -d "" POST http://127.0.0.1:8001/api/v1/users/settings/logout/

但作为回应,我收到了401 error - {"detail": "Authentication credentials were not provided."}。虽然用户已登录。

@action(detail=False, methods=['post'])
def logout(self, request):
    print(999)       #Nothing
    try:
        print(request.user.auth_token)
        request.user.auth_token.delete()
    except (AttributeError):
        pass
    from django.contrib.auth import logout
    logout(request)

    return Response({"success": _("Successfully logged out.")},
                    status=status.HTTP_200_OK)

好像连这个功能都不行了……

from django.contrib.auth import get_user_model

from rest_framework_jwt.authentication import JSONWebTokenAuthentication
from rest_framework import exceptions

from .utils import provide_user_to_sentry


class UserIdAuthenticateMixin:

    def authenticate_credentials(self, payload):
        """
        Returns an active user that matches the payload's user id.
        """
        User = get_user_model()
        user_id = payload.get('user_id')

        if not user_id:
            raise exceptions.AuthenticationFailed('Invalid payload.')

        try:
            user = User.objects.get(pk=user_id)
        except User.DoesNotExist:
            raise exceptions.AuthenticationFailed('Invalid signature.')

        if not user.is_active:
            raise exceptions.AuthenticationFailed('User account is disabled.')

        return user


class JSONWebTokenSentryAuthentication(UserIdAuthenticateMixin, JSONWebTokenAuthentication):
    """Wrapper around ``JSONWebTokenAuthentication``

    In case of successful authentication it reports user id and IP address to sentry for later logging

    Clients should authenticate by passing the token key in the "Authorization"
    HTTP header, prepended with the string specified in the setting
    `JWT_AUTH_HEADER_PREFIX`. For example:

        Authorization: JWT eyJhbGciOiAiSFMyNTYiLCAidHlwIj
    """
    def authenticate(self, request):
        original_response = super().authenticate(request)
        if original_response is None:
            return original_response

        user, _jwt = original_response
        provide_user_to_sentry(request, user)
        return original_response


class UserIdJSONWebTokenAuthentication(UserIdAuthenticateMixin, JSONWebTokenAuthentication):
    """Wrapper around ``JSONWebTokenAuthentication``

    Update authenticate_credentials to check user id.

    Clients should authenticate by passing the token key in the "Authorization"
    HTTP header, prepended with the string specified in the setting
    `JWT_AUTH_HEADER_PREFIX`. For example:

        Authorization: JWT eyJhbGciOiAiSFMyNTYiLCAidHlwIj
    """
    pass

【问题讨论】:

  • 您正在从命令行发出 curl 请求。那么说“用户已登录”是什么意思呢?什么用户?您没有用户。
  • 对不起。输入并获得token。如何使用drf 注销?
  • 嗯,要注销,你需要登录。正如错误明确指出的那样,你需要在请求中传递一个有效的令牌,以便 Django 可以对你进行身份验证并填写request.user。跨度>
  • 你能提供你的DEFAULT_AUTHENTICATION_CLASSES吗?默认情况下,在 DRF 上,它是 Authorization: Token xxxxxxx
  • Angular 端的注销可以像从本地存储中删除 JWT 令牌一样简单。无需调用服务器。

标签: django rest api django-rest-framework


【解决方案1】:

授权

在这个请求之后,我得到了用户的令牌

curl -H "Authorization: JWT Token" -d "email=test@gmail.com&password=password" POST 'http://127.0.0.1:8001/api/v1/users/login/'

注销视图

@action(detail=False, methods=['post'])
def logout(self, request):
    try:
        request.user.auth_token.delete()
    except (AttributeError, ObjectDoesNotExist):
        pass

    django_logout(request)
    return Response(status=status.HTTP_200_OK)

注销请求

curl -d "" -H "Authorization: JWT Token" POST 'http://127.0.0.1:8001/api/v1/users/settings/logout/'

【讨论】:

  • 好的,您的控制器可以工作,但请相信我,它实际上并没有做任何事情。由于您使用 JWT,因此没有要删除的 auth_token。所以你路过except 块。至于 Django logout 函数,它只是 flushes the session。所以除非你真的打算使用TokenAuthenticationSessionAuthentication,否则你不需要那个视图。
猜你喜欢
  • 2019-02-25
  • 2015-08-24
  • 2018-04-18
  • 2018-10-04
  • 2018-02-06
  • 2014-05-26
  • 2014-05-08
  • 2015-07-21
  • 2013-05-27
相关资源
最近更新 更多