广告
返回顶部
首页 > 资讯 > 后端开发 > Python >django restframework使用redis实现token认证
  • 210
分享到

django restframework使用redis实现token认证

2024-04-02 19:04:59 210人浏览 薄情痞子

Python 官方文档:入门教程 => 点击学习

摘要

目录一、前言二、详解1. 前期准备2. 配置Redis3. 将token写入redis3.1 原来的登录代码3.2 重写后的登录代码3.3 登录后redis存储的用户记录4. 重写认

一、前言

restframework有自己很方便的一套认证、权限体系:官方文档(tokenauthentication)

官方文档的token 是基于数据库中的authtoken_token表来做的

在这里插入图片描述

有时候在后续接口中需要使用的用户信息过多时,频繁、高并发下的查询数据库会带来比较大的性能消耗。这个时候我们就需要通过redis来做用户认证,并存储一些用户信息在其中。下面就为你讲解如何基于redis来使用DRF做用户认证。

二、详解

1. 前期准备

1.1 安装redis并启动

自行安装!这个都装不好后面的教程也不用看了!看了也理解不了!

1.2 安装Django-redis库


pip install djanGo-redis -i https://pypi.tuna.tsinghua.edu.cn/simple

2. 配置redis

2.1 配置redis连接

settings.py输入下面的代码 (我的redis没有设置密码,所以配置代码中无密码相关配置)


# redis缓存配置
CACHES = {
    "default": {
        "BACKEND": "django_redis.cache.RedisCache",
        "LOCATION": "redis://127.0.0.1:6379/",
        "OPTIONS": {
            "CLIENT_CLASS": "django_redis.client.DefaultClient",
            "COMPRESSOR": "django_redis.compressors.zlib.ZlibCompressor",
            "IGNORE_EXCEPTIONS": True,
        }
    }
}

2.2 初始化redis连接

项目初始化文件中(__init__.py)加入下面代码进行redis的初始化

在这里插入图片描述

加入下列代码


from django_redis import get_redis_connection
redis_connect = get_redis_connection()

3. 将token写入redis

在之前的登录接口是将token写入数据库的,现在需要重写它让其写入redis

3.1 原来的登录代码


@api_view(['POST'])
def login(request):
    """
    登录接口
    """
    user = authenticate(username=request.data['username'], passWord=request.data['password'])
    if user:
        Token.objects.filter(user_id=user.id).delete()
        token = Token.objects.create(user=user)
        _dict = {'id': user.id, 'username': user.username, 'first_name': user.first_name,
                 'last_name': user.last_name, 'email': user.email}        
        redis_connect.set(token.key, JSON.dumps(_dict), 259200)  # 存redis 259200秒=72个小时
        return Response(data={'status_code': 200, 'msg': '登录成功!', 'token': token.key})
    return Response(data={'status_code': 403, 'msg': '密码错误!'})

3.2 重写后的登录代码


@api_view(['POST'])
def login(request):
    """
    登录接口
    """
    user = authenticate(username=request.data['username'], password=request.data['password'])
    if user:
        token = binascii.hexlify(os.urandom(20)).decode()  # 生成token 的方式
        _dict = {'id': user.id, 'username': user.username, 'first_name': user.first_name,
                 'last_name': user.last_name, 'email': user.email}
        redis_connect.set(token, json.dumps(_dict), 259200)  # 存redis 259200秒=72个小时
        return Response(data={'status_code': 200, 'msg': '登录成功!', 'token': token})
    return Response(data={'status_code': 403, 'msg': '密码错误!'})

3.3 登录后redis存储的用户记录

在这里插入图片描述

4. 重写认证token方法

4.1 源码分析

我们可以全局搜索TokenAuthentication 找到【restframework】源码中的Token认证类

在这里插入图片描述

这个类中我们只需要关注authenticate_credentials这个方法就可以了。


    def authenticate_credentials(self, 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.'))

        return (token.user, token)

源码首先通过接口请求的token (源码中的key) 去数据库中寻找是否有该对应的记录
如果有则认证成功返回usertoken这两个模型对象

如果没有对应的记录,则抛出【invalid token】异常


        try:
            token = model.objects.select_related('user').get(key=key)
        except model.DoesNotExist:
            raise exceptions.AuthenticationFailed(_('Invalid token.'))

如果有对应的记录,但用户是未激活的 (is_active=0) 则抛出【User inactive or deleted】异常


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

然后restframework会在视图层的dispatch方法中进行异常的封装并返回响应结果。

4.2 进行重写

经过源码分析,我们需要重写的有两部分:

1.验证token (源码中的key) 是否有效,之前是从数据库进行验证的现在需要通过redis去验证

2.重新封装user模型对象,但有个问题需要注意的是:
如果你重写了django的user对象,让它关联了其他表的属性,那么这里则不能将其封装进user这个对象的,因为redis不能存储一个对象!,当然如果非要这么做可以将外键id值在登录 (写入token) 的时候存入redis,然后在这里通过该外键id去查询关联的外键表获取属性,再封装到user模型对象中!

重写后的代码


class RedisTokenAuthentication(TokenAuthentication):

    def authenticate_credentials(self, key):
        null = None  # json的None为null,所以需要定义一下
        user_data = redis_connect.get(key)
        if user_data:
            user_dict = json.loads(user_data)
            user_obj = User()
            for key_name in user_dict.keys():
                setattr(user_obj, key_name, user_dict[key_name])
            return user_obj, key
        raise exceptions.AuthenticationFailed(_('无效的token.'))

4.3 加入认证配置

settings.py配置文件中,加入如下配置


REST_FRAMEWORK = {
    'DEFAULT_AUTHENTICATION_CLASSES': (  #如果有REST_FRAMEWORK配置项了单独加入该项即可
        'Demo.RedisAuthentication.RedisTokenAuthentication',  # 项目名称.重新认证类所在的文件.类名
    ),
}

4.4 效果展示

增加一个接口


path('test-token', views.test_token),

接口方法代码


@api_view(['GET'])
@permission_classes((permissions.IsAuthenticated,))
def test_token(request):
    """
    测试token
    """
    print('登录的用户名是:', request.user)
    res_data = {'data': {'status_code': 200}}
    return Response(**res_data)

输出结果

登录的用户名是: admin

三、总结

无论是django还是restframework,他们的源码和官方文档在我看来是非常清晰的 (在我看的那么多官方文档中算很清晰的了) 这里给DRF的团队点个赞!!!

到此这篇关于django restframework使用redis实现token认证的文章就介绍到这了,更多相关django restframework token认证内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

--结束END--

本文标题: django restframework使用redis实现token认证

本文链接: https://www.lsjlt.com/news/136295.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • django restframework使用redis实现token认证
    目录一、前言二、详解1. 前期准备2. 配置redis3. 将token写入redis3.1 原来的登录代码3.2 重写后的登录代码3.3 登录后redis存储的用户记录4. 重写认...
    99+
    2022-11-12
  • SpringBoot使用Sa-Token实现登录认证
    目录一、设计思路二、登录与注销三、会话查询四、Token 查询五、来个小测试,加深一下理解一、设计思路 对于一些登录之后才能访问的接口(例如:查询我的账号资料),我们通常的做法是增加...
    99+
    2023-05-14
    SpringBoot Sa-Token登录认证 SpringBoot 登录认证
  • SpringBoot使用Sa-Token实现权限认证
    目录一、设计思路二、获取当前账号权限码集合三、权限校验四、角色校验五、拦截全局异常六、权限通配符七、如何把权限精确到按钮级?八、前端有了鉴权后端还需要鉴权吗?九、来个小示例,加深一下...
    99+
    2023-05-17
    SpringBoot Sa-Token权限认证 SpringBoot 权限认证
  • Django基于Token的验证使用的实现
    目录什么是Token为什么要用Token基于 Token 的身份验证流程Token的组成形式Django如何使用Token什么是Token Token字面意思是令牌,功能跟Sessi...
    99+
    2022-11-12
  • SpringBoot如何使用Sa-Token实现权限认证
    今天小编给大家分享一下SpringBoot如何使用Sa-Token实现权限认证的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。...
    99+
    2023-07-06
  • SpringBoot怎么使用Sa-Token实现登录认证
    这篇文章主要讲解了“SpringBoot怎么使用Sa-Token实现登录认证”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“SpringBoot怎么使用Sa-Token实现登录认证”吧!一、设...
    99+
    2023-07-05
  • ThinkPHP5实现JWT Token认证的过程(亲测可用)
    1、composer先挂载阿里云镜像 composer config -g repo.packagist composer https://mirrors.aliyun.com/co...
    99+
    2022-11-13
    ThinkPHP5 JWT Token认证 JWT Token认证 TP5环境jwt验证
  • 基于redis实现token验证用户是否登陆
    基于项目需求, 我们要实现一个基于redis实现token登录验证,该如何实现呢: 后端实现: 1.引入redis相关的依赖 <dependency> <groupId>org...
    99+
    2022-10-18
  • Django 中间件实现用户认证与IP频
    1.URL访问过滤 通过装饰器进行用户认证非常方便,但是在添加部分需要认证的功能时,就需要再次添加装饰器,如果通过中间件来实现,就不需要再进行添加的操作. import re LOGIN_URL = '/login/' class MyL...
    99+
    2023-01-30
    中间件 用户 Django
  • ThinkPHP6使用JWT+中间件实现Token验证
    目录 前言 一、JWT介绍 二、使用composer安装JWT扩展包  三、在ThinkPHP6中直接使用JWT生成验证Token(简单粗暴) (一)代码文件 (二)请求接口测试 四、在ThinkPHP6中使用JWT+中间件生成验证Tok...
    99+
    2023-09-01
    php 开发语言
  • go语言使用jwt认证的实现
    目录加密解密这几天在学习nodejs,进一步了解npm,学习过程中解开了以前的一个疑惑,以前不知道token可以携带信息,只以为是用来做对比的,学到了jwt身份认证,知道了如何使用的...
    99+
    2022-11-13
  • 怎么使用Golang语言实现Radius认证
    这篇“怎么使用Golang语言实现Radius认证”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“怎么使用Golang语言实现...
    99+
    2023-07-06
  • 利用Django内置的认证视图实现用户密码重置功能详解
    前言 密码重置功能相信对大家来说都不陌生,本文主要给大家介绍了关于使用Django内置的认证视图实现简单的通过邮箱重置密码的功能,分享出来供大家参考学习,下面话不多说了,来一起来看看详细的介绍吧。 版本:...
    99+
    2022-06-04
    视图 详解 用户密码
  • 使用Django实现商城验证码模块的方法
    本文主要涉及图形验证码的相关功能,主要包括,图形验证码获取、验证码文字存储、验证码生成等。 图形验证码接口设计和定义  验证码获取接口设计 uuid作为路径参数,唯一标识...
    99+
    2022-11-12
  • 如何使用HTML5实现人脸识别活体认证
    这篇文章主要为大家展示了“如何使用HTML5实现人脸识别活体认证”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“如何使用HTML5实现人脸识别活体认证”这篇文章吧...
    99+
    2022-10-19
  • laravel 中如何使用二维码实现身份认证?
    Laravel 中如何使用二维码实现身份认证? 二维码在现代社会已经普及,它不仅仅是一种方便的扫描方式,也成为了一种重要的安全认证方式。在 Laravel 中,我们可以使用二维码实现身份认证,提高系统的安全性。本文将介绍如何使用 Larav...
    99+
    2023-10-25
    二维码 laravel 面试
  • 使用django怎么实现发送验证码注册邮箱
    这篇文章将为大家详细讲解有关使用django怎么实现发送验证码注册邮箱,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。视图代码lis = []#设置一个空列表用来存放发送的...
    99+
    2023-06-14
  • Django中使用pillow实现登录验证码功能(带刷新验证码功能)
    首先在项目里建立common目录,编写验证码的函数 verification_code.py import random from PIL import Image, Imag...
    99+
    2022-11-12
  • SpringBoot使用Filter实现签名认证鉴权的示例代码
    情景说明         鉴权,有很多方案,如:SpringSecurity、Shiro、拦截器、过滤器等等。...
    99+
    2022-11-12
  • 如何使用Go语言和Redis实现用户身份验证
    如何使用Go语言和Redis实现用户身份验证一、简介在Web应用程序中,用户身份验证是必不可少的一个功能。用户需要提供有效的凭证,才能访问特定的资源或执行某些操作。Go语言是一种强大的编程语言,而Redis是一个快速、高可用的内存数据存储系...
    99+
    2023-10-26
    Go语言 redis 用户身份验证
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作