drf django rest auth 如何过期或删除令牌?

Posted

技术标签:

【中文标题】drf django rest auth 如何过期或删除令牌?【英文标题】:drf django rest auth how to expire or delete token? 【发布时间】:2016-10-11 05:28:39 【问题描述】:

我正在尝试使用 django-rest-frameworkdjango-rest-auth by tivix (link to documentation) 实现身份验证。我使用 django shell 创建了一个用户,例如:

from django.contrib.auth.models import User
user = User.objects.create_user(username='foo', email='foo@bar.com', password='bar')
user.save()

然后根据Documentation,我使用django-rest-auth 登录了一个用户,就像(终端命令):

curl -X POST -d "username=foo&password=bar&email=foo@bar.com" http://127.0.0.1:8000/rest-auth/login/

它返回了一个令牌,我知道用户已通过身份验证。

现在我使用 django-rest-auth 文档中描述的方法退出,我仍然可以看到数据库中存在的令牌。然后我再次登录,它返回与密钥相同的令牌。

那么有什么方法可以在每次用户注销时删除令牌更改或更好。此外,文档中也没有提及令牌本身是否会在一定时间过后过期(自动删除)。

如果不可能,在这两种情况下如何删除令牌?

编辑:登录和注销代码

urls.py(主要):

url(r'^rest-auth/', include('rest_auth.urls')),

settings.py:

INSTALLED_APPS = [
    ...
    'rest_framework',
    'rest_framework.authtoken',
    'rest_auth',
    ...
]

登录 CURL 命令:(如上所示)。 登录命令响应:

u'key': u'e41f0a1c2f5e55569df1c41d1d5d4efb77beddee'

注销 CURL 命令:

curl -X POST -d "key=e41f0a1c2f5e55569df1c41d1d5d4efb77beddee" http://127.0.0.1:8000/rest-auth/logout/

注销响应:

u'success': u'Successfully logged out.'

【问题讨论】:

你试过user.auth_token.delete()吗? @HåkenLid 因为我必须有权访问用户对象。我直接在 Angular 应用程序中提供登录 url,因为它返回令牌和注销相同。所以它使用包预定义视图。 您如何退出?你能显示代码和响应吗? api 视图端点应该会导致令牌被删除。 您必须在退出时使用令牌进行身份验证。我不确定为什么权限是AllowAny,但看起来即使用户未登录,视图也不会返回错误状态。github.com/Tivix/django-rest-auth/blob/v0.7.0/rest_auth/… @HåkenLid 我在发送注销 POST 请求时将令牌传递给数据。我还添加了登录和注销的 url 和 curl 请求。 【参考方案1】:

您必须先登录才能删除令牌。

以下是django-rest-auth 处理注销 (ref) 的方式:

def post(self, request):
    return self.logout(request)

def logout(self, request):
    try:
        request.user.auth_token.delete()
    except (AttributeError, ObjectDoesNotExist):
        pass

    logout(request)

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

所以要注销:

curl -X POST -H "Authorization: Token <token>" http://127.0.0.1:8000/rest-auth/logout/

请注意django-rest-auth 支持基于会话和 DRF 令牌身份验证。

这里是关于DRF Token Authentication 以及如何使用它的文档

编辑

添加了有关 DRF 令牌身份验证的信息

【讨论】:

这似乎是正确的。我感到困惑的是,当身份验证实际上没有成功时,注销视图返回状态 200 OK。 django-rest-auth github repo Why logout endpoint doesn't require authorization? 上有一个相关问题 @HåkenLid 如何在登录呼叫后检查用户是否登录?我的意思是在正常的 django 身份验证中,我可以通过if user.is_authenticated() 进行检查。那么我如何查看django-rest-auth?我认为用户没有登录。这就是为什么在注销时不会删除令牌。 @ManishGupta:令牌认证不同于“登录”。您必须为每个请求发送一个有效的令牌。所以只要客户端和服务器拥有相同的令牌,你就“登录”了。要准确调查LogoutView 中发生的情况,您可以编辑rest-auth/views.py 并添加调试器跟踪,例如pdb.set_trace() 或日志语句。 @ManishGupta 你是对的,你没有登录,因为你在帖子正文中发送密钥。我猜您没有正确设置授权标头。您可以通过点击 /rest-auth/user/ 或任何受保护的资源来检查您是否已登录。 我得到 'detail: "Successfully logged out."' 但我没有将令牌放在标题中。那么这个方法实际上在做什么呢?我还看到令牌仍然存在于数据库中。

以上是关于drf django rest auth 如何过期或删除令牌?的主要内容,如果未能解决你的问题,请参考以下文章

Django-rest-auth和AWS - 错误401

Django Rest Framework(DRF) Json Web Token(JWT) 身份验证和登录过程

Django-rest-auth 和 AWS - 错误 401

django-rest-auth 自定义注册无法保存额外字段

使用 Django-rest-auth 创建新用户时创建自定义用户模型

DRF序列化