RESTful API 的令牌认证:令牌是否应该定期更改? [英] Token Authentication for RESTful API: should the token be periodically changed?

查看:31
本文介绍了RESTful API 的令牌认证:令牌是否应该定期更改?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用 Django 和 django-rest-framework 构建 RESTful API.

I'm building a RESTful API with Django and django-rest-framework.

作为身份验证机制,我们选择了令牌身份验证",我已经按照 Django-REST-Framework 的文档实现了它,问题是,应用程序是否应该定期更新/更改令牌,如果是,如何更新?应该是移动应用程序需要更新令牌,还是网络应用程序应该自动完成?

As authentication mechanism we have chosen "Token Authentication" and I have already implemented it following Django-REST-Framework's documentation, the question is, should the application renew / change the Token periodically and if yes how? Should it be the mobile app that requires the token to be renewed or the web-app should do it autonomously?

最佳实践是什么?

这里有人对 Django REST Framework 有经验并且可以提出技术解决方案吗?

Anybody here experienced with Django REST Framework and could suggest a technical solution?

(最后一个问题的优先级较低)

(the last question has lower priority)

推荐答案

让移动客户端定期更新其身份验证令牌是一种很好的做法.这当然是由服务器来强制执行的.

It is good practice to have mobile clients periodically renew their authentication token. This of course is up to the server to enforce.

默认的 TokenAuthentication 类不支持此功能,但您可以对其进行扩展以实现此功能.

The default TokenAuthentication class does not support this, however you can extend it to achieve this functionality.

例如:

from rest_framework.authentication import TokenAuthentication, get_authorization_header
from rest_framework.exceptions import AuthenticationFailed

class ExpiringTokenAuthentication(TokenAuthentication):
    def authenticate_credentials(self, key):
        try:
            token = self.model.objects.get(key=key)
        except self.model.DoesNotExist:
            raise exceptions.AuthenticationFailed('Invalid token')

        if not token.user.is_active:
            raise exceptions.AuthenticationFailed('User inactive or deleted')

        # This is required for the time comparison
        utc_now = datetime.utcnow()
        utc_now = utc_now.replace(tzinfo=pytz.utc)

        if token.created < utc_now - timedelta(hours=24):
            raise exceptions.AuthenticationFailed('Token has expired')

        return token.user, token

还需要覆盖默认的rest框架登录视图,以便在登录完成时刷新令牌:

It is also required to override the default rest framework login view, so that the token is refreshed whenever a login is done:

class ObtainExpiringAuthToken(ObtainAuthToken):
    def post(self, request):
        serializer = self.serializer_class(data=request.data)
        if serializer.is_valid():
            token, created =  Token.objects.get_or_create(user=serializer.validated_data['user'])

            if not created:
                # update the created time of the token to keep it valid
                token.created = datetime.datetime.utcnow()
                token.save()

            return Response({'token': token.key})
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

obtain_expiring_auth_token = ObtainExpiringAuthToken.as_view()

不要忘记修改网址:

urlpatterns += patterns(
    '',
    url(r'^users/login/?$', '<path_to_file>.obtain_expiring_auth_token'),
)

这篇关于RESTful API 的令牌认证:令牌是否应该定期更改?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆