DRF Django Rest Auth如何使令牌过期或删除?

11

我正在尝试使用 tivix 的 django-rest-authdjango-rest-framework 实现身份验证(文档链接)。我像这样在 Django shell 中创建了一个用户:

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

根据文档,我使用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åken Lid
@HåkenLid,为此我必须访问用户对象。我直接在Angular应用程序中提供登录URL,因为它返回令牌,并且同样适用于注销。因此,它使用预定义视图的软件包。 - Manish Gupta
在注销时,您必须使用令牌进行身份验证。我不确定为什么权限是“AllowAny”,但看起来即使用户未登录,该视图也不会返回错误状态。https://github.com/Tivix/django-rest-auth/blob/v0.7.0/rest_auth/views.py#L55 - Håken Lid
@HåkenLid 我在发送注销POST请求时将令牌传递给数据。此外,我添加了登录和注销的URL和Curl请求。 - Manish Gupta
@HåkenLid 我也尝试过,但我仍然无法删除该令牌。 - Manish Gupta
显示剩余3条评论
1个回答

20

您需要登录以删除令牌。

这是 django-rest-auth 处理注销的方式(参考):

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令牌身份验证及其使用方法的文档。
编辑
添加关于DRF令牌身份验证的信息。

@HåkenLid,登录后如何检查用户是否已登录?我的意思是在正常的Django身份验证中,我可以通过if user.is_authenticated()进行检查。那么我该如何使用django-rest-auth进行检查呢?我认为用户没有成功登录。这就是为什么在注销时令牌没有被删除的原因。 - Manish Gupta
1
@ManishGupta:Token 认证与“登录”不同。您必须在每个请求中发送一个有效的令牌。只要客户端和服务器具有相同的令牌,您就可以“登录”。要调查“LogoutView”中确切发生了什么,您可以编辑“rest-auth/views.py”并添加调试器跟踪,例如 pdb.set_trace() 或日志语句。 - Håken Lid
1
@ManishGupta,你说得对,你没有登录,因为你在post body中发送了密钥。我猜你没有正确设置Authorization header。你可以通过访问/rest-auth/user/或任何受保护的资源来检查你是否已经登录。 - varnothing
4
我收到了 '{detail: "Successfully logged out."}' 的消息,但我没有在头信息中放置令牌。那么这个方法实际上是做什么的?我还看到令牌仍然存在于数据库中。 - Evan Zamir
@EvanZamir 的退出登录代码块是不言自明的。此外,请注意,此端点还支持基于会话的身份验证。因此,只有在使用会话或使用授权标头(令牌)登录时,令牌才会被删除。 - varnothing
显示剩余4条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接