• 【技术博客】JWT的认证机制Django项目中应用


    开发组在开发过程中,都不可避免地遇到了一些困难或问题,但都最终想出办法克服了。我们认为这样的经验是有必要记录下来的,因此就有了【技术博客】。


    # JWT的认证机制Django项目中应用

    这篇技术博客基于软件工程课程的VisualPytorch之上。本文小部分参考了https://jwt.io/introduction/

    前言-JWT是什么,为什么用JWT

    在做绝大部分数据库系统时(网站、小程序),登录注册肯定是一个绕不开的功能。一般来说传统的解决方案是基于session机制的认证,也就是客户端发送用户名密码给服务器,服务器端验证后创建一个session,把session的id返回客户端,客户端每次请求时带着session的id以此作为验证。

    从我的视角来看主要存在两个问题:

    (1) 给服务器压力大

    session一般保存在内存中,当然比较大的应用保存在Redis这类数据库中,通过session_id来做认证增加了访存次数,影响性能。

    (2) 单点登录的问题

    如果你的应用需要支持通过微信号、QQ号登录,session_id的方式显然很成问题,毕竟你不可能拿到腾讯的数据库里的内容。

    这里就考虑了使用JWT机制来进行认证。JWT全称是JSON WEB TOKEN,如果使用JWT进行认证,服务器端不需要保存信息,因为JWT将信息加密到了token里。用户只需要每次请求的时候带着token即可,服务器会自己解密。

    需要补充的一点是,JWT和session机制并不冲突,如果你的应用对于session有需求,可以使用JWT做认证,session做其他需求。

    如果想比较详细地了解JWT,可以参考RFC7519

    Django中JWT解决方案

    有一个基于Django Restful接口的包可以用

    pip install djangorestframework-jwt
    

    详细使用方法参照官方文档

    该中间件主要提供了三个接口

    #获得token
    from rest_framework_jwt.views import obtain_jwt_token
    #刷新token
    from rest_framework_jwt.views import refresh_jwt_token
    #验证token
    from rest_framework_jwt.views import verify_jwt_token
    

    登录时调用obtain_jwt_token即可。

    而对于需要验证用户权限的接口,需要在settings.py中添加

     'DEFAULT_AUTHENTICATION_CLASSES': [
            'rest_framework_jwt.authentication.JSONWebTokenAuthentication',
            'rest_framework.authentication.SessionAuthentication',
            'rest_framework.authentication.BasicAuthentication'
        ]
    

    随后在接口层中增加需要的权限即可自动利用jwt来验证(不需要调用上文提到的verify_jwt_token),例如

    permission_classes = (permissions.IsAuthenticated,)
    

    如何修改验证登录方式

    这个其实和JWT无关,和Django有关,但既然都是一个项目下的,不妨多写一下,以防有需求。

    方法重写Django中User的的后端类中的authenticate方法,并且在settings.py中添加

    AUTHENTICATION_BACKENDS = [
        'user.utils.UserAuthBackend',  # 修改auth认证后端类,这里要写你自己新写的验证类
    ]
    

    我重写验证方法的代码如下,仅供参考

    from django.contrib.auth.backends import ModelBackend
    from .models import User
    from django.db.models import Q
    
    
    class UserAuthBackend(ModelBackend):
    
        def authenticate(self, request, username=None, password=None, **kwargs):
    
            # 邮箱或用户名登录
            try:
                user = User.objects.get(Q(username=username) | Q(email=username))
            except User.DoesNotExist:
                return None
            else:
                if user.check_password(password) and self.user_can_authenticate(user):
                    return user
    

    关与token有效时间与刷新

    这个中间价的默认设置一个token有效时间为300s,token与其子孙token的过期时间为7天。

    也就是说每隔300s都必须刷新当前的token,而隔7天的话刷新也无用必须重新获取。

    需要更改设置可以参考官方文档。


  • 相关阅读:
    jsp 说明标签
    atcoder 它February 29th
    centos编译内核:no space left on device 解
    《Javascript权威指南》十六学习笔记:BOM资源---BOM基本应用
    2014ACM/ICPC亚洲区域赛牡丹江站汇总
    Swift_3_功能
    ExtJs在disabled和readOnly美学分析
    android -- 蓝牙 bluetooth (四)OPP文件传输
    android -- 蓝牙 bluetooth (三)搜索蓝牙
    android -- 蓝牙 bluetooth (二) 打开蓝牙
  • 原文地址:https://www.cnblogs.com/1606-huluwa/p/10897827.html
Copyright © 2020-2023  润新知