【问题标题】:What is the point of having "logout" endpoint in django-rest-auth?在 django-rest-auth 中有“注销”端点有什么意义?
【发布时间】:2017-03-14 01:48:45
【问题描述】:

this 的文章我读过基于令牌的身份验证是无状态的,这意味着服务器不会保留登录用户的记录。

另一方面,在django-rest-auth API docs 中提到了一个注销端点。有什么用?

【问题讨论】:

  • 老问题...但这是因为如果您使用他们的 SessionMiddleware,Django 不使用基于令牌的身份验证,他们存储登录用户的信息。

标签: django rest authentication django-rest-auth


【解决方案1】:

在注销期间,颁发给用户的身份验证令牌被删除。您可以查看logout source,它调用request.user.auth_token.delete()。因此,下次用户登录时,将颁发一个新的令牌。

【讨论】:

  • 这是真的吗?我只是想使用这个包实现注销功能,但是成功注销后,令牌仍然在数据库中,如果我将“令牌 soCalledDeletedToken”放在请求标头中,我仍然可以访问该页面。
  • 我遇到了类似的问题。事实证明,我没有全局启用身份验证。所以,当我打电话给logout 时,即使我包含了凭据,它也被作为匿名用户处理。因此,实际用户的令牌没有被删除。希望这会有所帮助,
  • @Demetris 您如何全局启用身份验证?我已经按照文档中的说明配置了身份验证方案(请参阅最后的链接),看起来这就是您的意思,对吧?但是我的令牌在注销时仍然没有被删除。 django-rest-framework.org/api-guide/authentication/…
  • @RikSchoonbeek 是的,这就是我所指的。将DEFAULT_AUTHENTICATION_CLASSES 设置为rest_framework.authentication.TokenAuthentication
  • 命名空间DEFAULT_AUTHENTICATION_CLASSESREST_FRAMEWORK也是必须的。
【解决方案2】:

如果您将 JWT 选项与 django-rest-auth 一起使用,注销行为实际上并不会删除 JWT 令牌。所以它似乎基本上什么都不做。现在我还是 JWT 的新手,但根据我所学到的 - 似乎这甚至没有必要。所以只需在客户端上删除就可以了。仍然有一个 JUST-DESTROY-THE-JWT-TOKEN-BECAUSE-WHO-NEEDS-POTENTIALLY-UNEXPIRED-DANGEROUS-STUFF-HANGING-AROUND 选项会很好。但遗憾的是,我不认为 rest_framework_jwt 支持这一点。

rest_framework_simplejwt (https://github.com/davesque/django-rest-framework-simplejwt) 似乎确实支持这种很有希望的“黑名单”! (rest_framework_simplejwt.token_blacklist) 然而,唉,rest_auth 不支持 simplejwt,直截了当 - 嗯。如果有人弄清楚如何做到这一点,我会玩。

但回到 rest-auth 的 jwt 实现的情况......

因此,当您注销时,它确实会尝试删除 django 令牌,但我不相信这是您在这里所做的,因为如果您使用 JSONWebTokenAuthentication 类,您的 settings.py 中应该有以下内容:

settings.py(用于 JWT)

'DEFAULT_AUTHENTICATION_CLASSES': (
    'rest_framework_jwt.authentication.JSONWebTokenAuthentication', # USED BY JWT.
    'rest_framework.authentication.TokenAuthentication', # IGNORED BY JWT
)

现在当 django-rest-auth 去执行 /logout 时,让我们看看他们在 https://github.com/Tivix/django-rest-auth/blob/master/rest_auth/views.py 上的源代码在做什么

views.py(来自 rest-auth 源)

from django.contrib.auth import (
    login as django_login,
    logout as django_logout
)

from .models import TokenModel


#-------snip-------


class LogoutView(APIView):
    """
    Calls Django logout method and delete the Token object
    assigned to the current User object.
    Accepts/Returns nothing.
    """
    permission_classes = (AllowAny,)

    def get(self, request, *args, **kwargs):
        if getattr(settings, 'ACCOUNT_LOGOUT_ON_GET', False):
            response = self.logout(request)
        else:
            response = self.http_method_not_allowed(request, *args, **kwargs)

        return self.finalize_response(request, response, *args, **kwargs)

    def post(self, request, *args, **kwargs):
        return self.logout(request)

    def logout(self, request):
        try:
            request.user.auth_token.delete()
        except (AttributeError, ObjectDoesNotExist):
            pass
        if getattr(settings, 'REST_SESSION_LOGIN', True):
            django_logout(request)

        response = Response({"detail": _("Successfully logged out.")},
                            status=status.HTTP_200_OK)
        if getattr(settings, 'REST_USE_JWT', False):
            from rest_framework_jwt.settings import api_settings as jwt_settings
            if jwt_settings.JWT_AUTH_COOKIE:
                response.delete_cookie(jwt_settings.JWT_AUTH_COOKIE)
return response

models.py(来自 rest-auth 源)

from django.conf import settings

from rest_framework.authtoken.models import Token as DefaultTokenModel

from .utils import import_callable

# Register your models here.

TokenModel = import_callable(
getattr(settings, 'REST_AUTH_TOKEN_MODEL', DefaultTokenModel))

因此,除非您已将设置中的 REST_AUTH_TOKEN_MODEL 属性设置为自定义令牌模型(请参阅 https://github.com/Tivix/django-rest-auth/blob/master/docs/configuration.rst - 这是值得怀疑的,让我们在这里说实话。谁在这样做......),那么它只是试图删除 DefaultTokenModel - 这是我们没有使用的 django_token/session 身份验证模型。

我确实希望事情迁移到 simplejwt,因为它得到了更积极的支持。

我也希望这个brain-dump/jwt 挖掘对某人有所帮助。

附:关于 JWT、最佳使用和黑名单的更多信息。 https://dev.to/_arpy/how-to-log-out-when-using-jwt-4ajm

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-07-23
    • 2022-08-18
    • 1970-01-01
    • 1970-01-01
    • 2011-01-07
    • 2016-04-07
    • 1970-01-01
    • 2015-07-10
    相关资源
    最近更新 更多