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-framework
和 django-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 Framework(DRF) Json Web Token(JWT) 身份验证和登录过程
Django-rest-auth 和 AWS - 错误 401
django-rest-auth 自定义注册无法保存额外字段