RESTful API的令牌身份验证:应该如何定期更改令牌? [英] Token Authentication for RESTful API: should the token be periodically changed?

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

问题描述

我正在使用Django和 django-rest-framework 构建一个RESTful API。 / p>

作为身份验证机制,我们选择了令牌验证,并且我已经在Django-REST-Framework的文档之后实现了它,问题是,如果应用程序更新/更改令牌如果是的话呢?应该是移动应用程序需要更新令牌或网络应用程序自主执行吗?



最佳做法是什么?



任何人都会遇到Django REST框架,并可以提出技术解决方案?



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

解决方案

让移动客户端定期更新身份验证令牌是个好习惯。这当然取决于服务器来执行。



默认的TokenAuthentication类不支持此功能,但是您可以扩展它来实现此功能。



例如:

  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)
除了self.model.DoesNotExist:
raise exception.AuthenticationFailed('Invalid token')

如果不是token.user.is_active:
raise exception.AuthenticationFailed('User inactive or deleted')

#这是时间比较所需的
utc_now = datetime.utcnow()
utc_now = utc_now .replace(tzinfo = pytz .utc)

如果token.created< utc_now - timedelta(hours = 24):
raise exception.AuthenticationFailed('Token has expired')

返回token.user,令牌
/ pre>

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

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

如果未创建:
#更新令牌的创建时间以保持有效
token.created = datetime.datetime.utcnow()
token.save()

返回响应({ 'token':token.key})
return响应(serializer.errors,status = status.HTTP_400_BAD_REQUEST )

gets_expiring_auth_token = ObtainExpiringAuthToken.as_view()

不要忘记修改URL:

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


I'm building a RESTful API with Django and 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?

What is the best practice?

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.

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

For example:

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

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()

And don't forget to modify the urls:

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

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

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