`

优化Django Rest Framework 的Token验证功能

阅读更多

pi的通信采用token + ssl,简化和方便线上脚本的调用。Django版本1.8.16,djangorestframework版本3.5.3,用了框架提供的rest_framework.authtoken.views.obtain_auth_token和rest_framework.authentication.TokenAuthentication后,发现了一个问题,前者认证通过创建token后,这个token就不会自动更新了,非常不安全,非常危险。后者验证时候是不带缓存的,需要查询数据库,由于每次请求都要验证token,请求相当频繁,感觉不是很爽。

1、实现生成的token带过期时间
首先在setting.py配置文件设置过期时间 REST_FRAMEWORK_TOKEN_EXPIRE_MINUTES,这里设置为60分钟

#
REST_FRAMEWORK_TOKEN_EXPIRE_MINUTES = 60
#

setting.py同目录文件view.py编辑一个视图

#
#coding=utf8
import datetime
from django.conf import settings
from rest_framework import status
from rest_framework.response import Response
from rest_framework.authtoken.models import Token
from rest_framework.authtoken.views import ObtainAuthToken
 
EXPIRE_MINUTES = getattr(settings, 'REST_FRAMEWORK_TOKEN_EXPIRE_MINUTES', 1)
 
class ObtainExpiringAuthToken(ObtainAuthToken):
    """Create user token"""
    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'])
 
            time_now = datetime.datetime.now()
 
            if created or token.created < time_now - datetime.timedelta(minutes=EXPIRE_MINUTES):
                # Update the created time of the token to keep it valid
                token.delete()
                token = Token.objects.create(user=serializer.validated_data['user'])
                token.created = time_now
                token.save()
 
            return Response({'token': token.key})
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
 
obtain_expiring_auth_token = ObtainExpiringAuthToken.as_view()
#

url.py新增url用于生成用户token

#
#from rest_framework.authtoken.views import obtain_auth_token
from .views import obtain_expiring_auth_token
 
urlpatterns += [
    #url(r'^api/token/', obtain_auth_token, name='api-token'),
    url(r'^api/token/', obtain_expiring_auth_token, name='api-token'),
]
#

用curl测试接口 api/token/

#
git:(master) ✗ curl -H "Content-Type: application/json" -X POST -d '{"username":"test","password":"test"}' http://127.0.0.1:9000/api/token/
{"token":"6ff54785241f825846e4c5fca61cceb6be7f911e"}%
#

然后,然后这个生成token的接口就好了。目前还有一个问题,用户就是生成一个token例如A,然后用户再也不来请求这个接口生成token,那么这个用户的token A也会一直生效且不会被更新,那么要需要结合token验证函数,来强制删除用户过期的token。

2、自定义token验证,强制删除过期的token,顺便缓存下没有过期的token
首先在setting.py文件新增全局认证类api.authentication.ExpiringTokenAuthentication替换默认的rest_framework.authentication.TokenAuthentication

#
REST_FRAMEWORK = {
    'DEFAULT_AUTHENTICATION_CLASSES': [
        'rest_framework.authentication.BasicAuthentication',
        #'rest_framework.authentication.TokenAuthentication',  #enable Token authentication
        'api.authentication.ExpiringTokenAuthentication'
    ],
    'PAGE_SIZE': 10,
}
#

新建authentication.py文件,改文件在api这个目录下面。

#
#coding=utf8
import datetime
from django.conf import settings
from rest_framework.authentication import TokenAuthentication
from rest_framework import exceptions
from django.utils.translation import ugettext_lazy as _
 
from django.core.cache import cache
 
EXPIRE_MINUTES = getattr(settings, 'REST_FRAMEWORK_TOKEN_EXPIRE_MINUTES', 1)
 
class ExpiringTokenAuthentication(TokenAuthentication):
    """Set up token expired time"""
    def authenticate_credentials(self, key):
        # Search token in cache
        cache_user = cache.get(key)
        if cache_user:
            return (cache_user, key)
 
        model = self.get_model()
        try:
            token = model.objects.select_related('user').get(key=key)
        except model.DoesNotExist:
            raise exceptions.AuthenticationFailed(_('Invalid token.'))
 
        if not token.user.is_active:
            raise exceptions.AuthenticationFailed(_('User inactive or deleted.'))
 
        time_now = datetime.datetime.now()
 
        if token.created < time_now - datetime.timedelta(minutes=EXPIRE_MINUTES):
            token.delete()
            raise exceptions.AuthenticationFailed(_('Token has expired then delete.'))
 
        if token:
            # Cache token
            cache.set(key, token.user, EXPIRE_MINUTES * 60)
 
        return (token.user, token)
#

然后然后,所有的功能都实现了,删除用户过期的token和缓存token减少数据库查询。

 

分享到:
评论

相关推荐

    Django REST framework讲义PDF全集,中文文档PDF版

    Django REST Framework(DRF)是基于Python的Django Web框架的一个强大扩展,专为构建Web API而设计。本讲义全面涵盖了这个框架的核心概念、功能以及最佳实践,旨在帮助开发者快速掌握如何利用DRF创建高效、可维护的...

    django rest framework vue 实现用户登录详解

    在Django REST framework中实现用户登录,需要在Django的视图(views.py)中编写API接口,通常使用TokenAuthentication或SessionAuthentication这两种认证方式。 #### TokenAuthentication 使用TokenAuthentication...

    Django restframework课件笔记详解

    Django REST framework(简称DRF)是Python Web开发领域中一个强大的工具,专门用于构建Web API。这个框架基于Django,提供了许多高级特性,使得开发者能够高效、灵活地构建高质量的RESTful API服务。本课件笔记将...

    django-rest-framework 官方文档

    Django REST Framework拥有丰富的第三方扩展,如drf-extensions、drf-yasg(用于生成Swagger UI文档)等,可以进一步增强功能。 总之,Django REST Framework是构建高质量、可维护的RESTful API的理想选择。通过...

    基于django restframework.zip

    4. 认证与授权:Django REST framework内置了多种认证和授权策略,如Basic Auth、Token Auth、Session Auth等,可以根据项目需求选择合适的方式确保API的安全性。 5. 权限控制:框架允许自定义权限类,以便根据用户...

    Django rest framework中文

    通过上述介绍,我们可以看到Django REST framework在创建RESTful API方面的强大功能和灵活性。它提供了大量组件和工具,旨在帮助开发者提高开发效率、确保API的安全性与扩展性。尽管本文是基于一定版本的Django和...

    Python库 | django-rest-framework-social-oauth2-1.0.1.tar.gz

    `django-rest-framework-social-oauth2` 是一个基于 Django Rest Framework 的社交认证扩展库,主要用于实现 OAuth2 身份验证流程。这个库使得 Django 应用能够轻松地集成各种社交媒体登录服务,如 Facebook、Google...

    django rest framework

    **Django REST Framework详解** Django REST Framework(简称DRF)是基于Python的Django Web框架构建RESTful API的强大工具。它提供了一套完整的解决方案,包括序列化、身份验证、权限控制、分页以及Web视图,使得...

    基于Django框架,使用Django REST framework前后端分离技术搭建的网上图书商店.zip

    在Django REST framework中,可以通过Token认证、Session认证等多种方式进行用户验证。项目可能采用了这些机制之一,确保只有合法用户能访问和操作图书商店的资源。 7. 数据库模型: Django中的数据库模型定义了...

    Python-DjangoREST框架的无密码验证

    在Python的Web开发领域,Django REST框架(Django REST framework,简称DRF)是一个强大的工具,用于构建可扩展的、高性能的APIs。而"Python-Django REST框架的无密码验证"则涉及到了现代应用中的一种身份验证方法,...

    rest-framework生成token

    使用rest-framework在django中创建和认证token,用于在移动端来认证和用户,本文通过自己编写模型来实现根据用户来生成token,在请求头中添加Authentication来进行认证,保持登录状态。可以直接使用,编写过程可以...

    django rest framework 源码包

    深入理解并掌握Django REST Framework的源码,不仅可以帮助我们优化API的设计,还能提升代码质量和开发效率。源码包的下载和研究将有助于我们了解其内部工作原理,从而更好地利用这个强大的工具。

    django-rest-framework-cn

    ### Django REST Framework 知识点解析 #### 一、简介 Django REST Framework...综上所述,Django REST Framework不仅提供了强大的功能支持,而且通过高度可配置性和扩展性使得开发者能够快速构建高质量的Web API。

    django rest framework 实现用户登录认证详解

    在众多Web框架中,Django REST framework因其灵活性和功能强大而受到开发者的青睐,特别是在构建RESTful API时。今天我们将详细探讨如何使用Django REST framework实现用户登录认证。 Django REST framework(DRF)...

    Building APIs with Django and Django Rest Framework

    ### 构建API:使用Django与Django Rest Framework #### 一、简介 构建API:使用Django与Django Rest Framework这本书旨在帮助读者掌握如何使用Django框架及其流行的扩展库——Django Rest Framework(简称DRF)来...

    django-rest-framework-simplejwt-master_oppositemeq_encryption_dj

    接下来,“simplejwt”是指“Django REST Framework Simple JWT”,这是一个流行的身份验证库,它实现了JSON Web Token(JWT)认证机制。最后,“master”通常表示这是项目仓库的主分支。 **描述解析:** "Simple ...

    PyPI 官网下载 | django_restframework_apiview-1.3.26.tar.gz

    **PyPI 官网下载 | django_restframework_apiview-1.3.26.tar.gz** 这个压缩包文件“django_restframework_apiview-1.3.26.tar.gz”来源于Python的官方软件仓库PyPI(Python Package Index),它是Python开发者们...

    Django REST进阶学习资料

    Django REST Framework(简称DRF)是基于Python的Django Web框架的一个强大的扩展,它为构建Web API提供了高效、易用的工具集。本进阶学习资料将带你深入理解Django REST的高级特性,帮助你从初级用户晋升为熟练...

    Django Rest framework之权限的实现示例

    为了更好的管理各个功能组件,在django rest framework 之 认证 中我们说到可以将认证类单独的拿出来,放到其他目录下,然后导入到 views.py 文件中,在权限环节我们亦可以这么做,目录结构就变成这样 在api这个app...

Global site tag (gtag.js) - Google Analytics