JWT和频率模块

JWT

jwt基本介绍

全称:json web token

随着技术的发展,分布式web应用的普及,通过session管理用户登录状态成本越来越高,因此慢慢发展成为token的方式做登录身份校验,然后通过token去取redis中的缓存的用户信息,随着之后jwt的出现,校验方式更加简单便捷化,无需通过redis缓存,而是直接根据token取出保存的用户信息,以及对token可用性校验,单点登录更为简单。

token的格式

三段式 - 头.载荷.签名 - 头和载荷采用的是base64可逆加密,签名采用的是MD5不可逆加密

token内容

? 头(基础信息,也可以为空):加密方式、公司信息、项目组信息、...
? 载荷(核心信息):用户信息、过期时间、...
? 签名(安全保障):头加密结果+载荷加密结果+服务器秘钥 的md5加密结果

安全保障

安全保障主要靠的就是签名部分,比如Django的服务器密钥就是唯一的安全保障

认证规则

后台一定要保障 服务器秘钥 的安全性(它是jwt的唯一安全保障)
后台签发token -> 前台存储 -> 发送需要认证的请求带着token -> 后台校验得到合法的用户

使用jwt

对认证模块进行封装,登录成功返回加密的token,还有解析token的功能

首先要安装jwt。

pip install djangorestframework-jwt

jwt的三个主要功能

三个视图接口

jwt默认实现的功能过于简单,所以一般不直接使用他提供的视图接口

url(r'^login1/$', obtain_jwt_token),

#签发token,接收username和password
obtain_jwt_token = ObtainJSONWebToken.as_view()

#校验token,验证token,对的原样返回,错的报错
refresh_jwt_token = RefreshJSONWebToken.as_view()

#刷新token,使用要配置'JWT_ALLOW_REFRESH': False,允许刷新为True,token过期,刷新为有效时间
verify_jwt_token = VerifyJSONWebToken.as_view()

jwt配置

JWT_AUTH = {
    'JWT_EXPIRATION_DELTA': datetime.timedelta(days=7),

    # 'JWT_ALLOW_REFRESH': True,
    # 'JWT_REFRESH_EXPIRATION_DELTA': datetime.timedelta(days=7),

    'JWT_AUTH_HEADER_PREFIX': 'JWT',
}

签发token流程

user-->jwt_payload_handler-->payload-->jwt_encode_handler-->token

#全局钩子,登录之后在序列化类里面做校验的时候就直接签发token。
   def validate(self, attrs):
        user = authenticate(**attrs)
        if not user:
            raise ValidationError({'user':'信息有误'})
        payload = jwt_payload_handler(user)
        token = jwt_encode_handler(payload)

        self.user = user
        self.token = token

        return attrs

jwt全局认证

# drf的配置
REST_FRAMEWORK = {
    # 异常模块
    'EXCEPTION_HANDLER': 'utils.exception.exception_handler',

    # 认证模块
    'DEFAULT_AUTHENTICATION_CLASSES': [
        # jwt认证类
        'rest_framework_jwt.authentication.JSONWebTokenAuthentication',
    ],
    # 权限模块
    'DEFAULT_PERMISSION_CLASSES': [
        # 'rest_framework.permissions.IsAuthenticated',
        # 自定义权限类
    ],
    # 频率设置
    'DEFAULT_THROTTLE_RATES': {
        'three': '3/min',
    },
}

# 修改auth模块的用户表指向
AUTH_USER_MODEL = 'api.User'

# drf-jwt配置
import datetime
JWT_AUTH = {
    'JWT_EXPIRATION_DELTA': datetime.timedelta(days=7),

    # 'JWT_ALLOW_REFRESH': True,
    # 'JWT_REFRESH_EXPIRATION_DELTA': datetime.timedelta(days=7),

    'JWT_AUTH_HEADER_PREFIX': 'JWT',
}

多重登录

class LoginAPIView(APIView):
    authentication_classes = []
    permission_classes = []
    def post(self, request, *args, **kwargs):
        serializer = serializers.LoginSerializer(data=request.data)
        serializer.is_valid(raise_exception=True)
        return APIResponse(msg='login success', data={
            'username': serializer.user.username,
            'token': serializer.token
        })

serializers:

from rest_framework_jwt.serializers import jwt_payload_handler, jwt_encode_handler
class LoginSerializer(ModelSerializer):
    username = CharField(write_only=True)
    password = CharField(write_only=True)
    class Meta:
        model = models.User
        fields = ('username', 'password')

    # 在全局钩子中签发token
    def validate(self, attrs):
        # user = authenticate(**attrs)
        # 账号密码登录 => 多方式登录
        user = self._many_method_login(**attrs)

        # 签发token,并将user和token存放到序列化对象中
        payload = jwt_payload_handler(user)
        token = jwt_encode_handler(payload)

        self.user = user
        self.token = token

        return attrs

    # 多方式登录
    def _many_method_login(self, **attrs):
        username = attrs.get('username')
        password = attrs.get('password')
        if re.match(r'.*@.*', username):
            user = models.User.objects.filter(email=username).first()  # type: models.User

        elif re.match(r'^1[3-9][0-9]{9}$', username):
            user = models.User.objects.filter(mobile=username).first()
        else:
            user = models.User.objects.filter(username=username).first()

        if not user:
            raise ValidationError({'username': '账号有误'})

        if not user.check_password(password):
            raise ValidationError({'password': '密码有误'})

        return user

综述一下 jwt

就是三句代码,一句payload,一句token,一句settings的配置

他帮你完成了用户认证,所以你只用写三大认证中的权限认证和频率认证。你只需要做的是,把用jwt把token生成了,然后放在user的名称空间里,校验token,由你在settings里配置的jwt部分来完成。

频率模块

自定义频率类完成视图类的频率限制
1)定义类继承SimpleRateThrottle,重写get_cache_key方法,设置scope类属性
2)scope就是一个认证字符串,在配置文件中配置scope字符串对应的频率设置
3)get_cache_key的返回值是字符串,该字符串是缓存访问次数的缓存key

在settings里的drf配置中写上这个

'DEFAULT_THROTTLE_RATES': {
        'three': '3/min',
    },

要自定义频率的视图类

from rest_framework.permissions import IsAuthenticated
from utils.throttles import ThreeTimeUserThrottle
class UserCenterAPIView(APIView):
    # 认证全局配置吗,权限局部配置,认证已经交给jwt了
    # authentication_classes = []
    permission_classes = [IsAuthenticated]
    # 频率模块局部配置
    throttle_classes = [ThreeTimeUserThrottle]

    def get(self, request, *args, **kwargs):
        user = request.user
        serializer = serializers.UserModelSerializer(user)
        return APIResponse(data=serializer.data)

throttles

# 自定义频率类
from rest_framework.throttling import SimpleRateThrottle
# 1)定义类继承SimpleRateThrottle,重写get_cache_key方法,设置scope类属性
# 2)scope就是一个认证字符串,在配置文件中配置scope字符串对应的频率设置
# 3)get_cache_key的返回值是字符串,该字符串是缓存访问次数的缓存key
class ThreeTimeUserThrottle(SimpleRateThrottle):
    #这里的scope要和settings里面的key对上。
    scope = 'three'
    # 当前用户缓存的key,这个方法的返回值是一个能够唯一标识用户的信息,如果name是唯一的,用name也行,总之它会认得这个字符串,知道下次进来的人是不是你。如果返回的字符串每次都是同样的,那么你所有用户登录就共用一个频率了。
    def get_cache_key(self, request, view):
        return 'throttle:user_%s' % (request.user.id)

原文地址:https://www.cnblogs.com/chanyuli/p/11966208.html

时间: 2024-10-13 06:46:10

JWT和频率模块的相关文章

XGoServer 一个基础性、模块完整且安全可靠的服务端框架

作者:林冠宏 / 指尖下的幽灵 掘金:https://juejin.im/user/587f0dfe128fe100570ce2d8 博客:http://www.cnblogs.com/linguanh/ GitHub : https://github.com/af913337456/ 腾讯云专栏: https://cloud.tencent.com/developer/user/1148436/activities 一个基础性.模块完整且安全可靠的服务端框架 开源地址:https://gith

python实现后台系统的JWT认证

介绍一种适用于restful+json的API认证方法,这个方法是基于jwt,并且加入了一些从oauth2.0借鉴的改良. 1. 常见的几种实现认证的方法 首先要明白,认证和鉴权是不同的.认证是判定用户的合法性,鉴权是判定用户的权限级别是否可执行后续操作.这里所讲的仅含认证.认证有几种方法: 1.1 basic auth 这是http协议中所带带基本认证,是一种简单为上的认证方式.原理是在每个请求的header中添加用户名和密码的字符串(格式为“username:password”,用base6

软件测试第四周作业 WordCount优化

Github地址 https://github.com/husterC/WordCountGroupwork PSP表格 PSP2.1 PSP阶段 预估耗时 (分钟) 实际耗时 (分钟) Planning 计划     · Estimate · 估计这个任务需要多少时间 540  780 Development 开发     · Analysis · 需求分析 (包括学习新技术)  60  120 · Design Spec · 生成设计文档  30  10 · Design Review ·

2018-8-6对美多商城项目的总结

2018-8-6对美多商城项目的总结 美多商城商业模式: C2B模式(消费者到企业的商业模式),相类似网站包括:京东,淘宝,海尔商城,尚品宅配等. 商城需求分析 1,用户部分 2,商品部分 3,购物车部分 4,商品订单备份 5,用户支付部分 6,上线程序的配置 用户部分模块: 基本功能:用户注册,登录,密码的重置,第三方登录 用户注册 1,图片验证码 流程分析: 1,前端生成uuid随机字符串 2,后端生成图片验证码发送给前端,将图形验证码的存入到redis中 2,短信验证码 1,检查图片的验证

DRF-JWT

DRF-JWT 一.JWT JWT全称: json web token, 作用:将原始的数据json加密成字符串,通过后台将加密的字符串给前台存储(token) 格式:三段式,头.载荷.签名 , 头和载荷都是采用base34可逆加密,签名采用md5不可逆加密 头(基础信息,也可以为空):加密方式.公司信息.项目中信息.... 载荷(核心信息): 用户信息.过期时间... 签名(安全保障): 头加密结果+载荷加密结果+服务器秘钥的md5加密的结果 注意:后台一定要保障服务器秘钥的安全,他是jwt唯

频率类组件-认证规图分析-JWT认证-drf-jwt插件

频率类源码 # 1)APIView的dispath方法中的 self.initial(request, *args, **kwargs) 点进去 # 2)self.check_throttles(request) 进行频率认证 频率组件原理分析 频率组件的核心源码分析 def check_throttles(self, request): throttle_durations = [] # 1)遍历配置的频率认证类,初始化得到一个个频率认证类对象(会调用频率认证类的 __init__() 方法)

DRF -- 频率组件 JWT使用

频率类源码 入口 # 1)APIView的dispath方法中的 self.initial(request, *args, **kwargs) 点进去 # 2)self.check_throttles(request) 进行频率认证 # 频率组件核心源码分析 def check_throttles(self, request): throttle_durations = [] # 1)遍历配置的频率认证类,初始化得到一个个频率认证类对象(会调用频率认证类的 __init__() 方法) # 2)

Android FM模块学习之二 FM搜索频率流程

上一篇大概分析了一下FM启动流程,若不了解Fm启动流程的,能够去打开前面的链接先了解FM启动流程,接下来我们简单分析一下FM的搜索频率流程. 在了解源代码之前.我们先看一下流程图: 事实上从图中能够看到,实现搜索频率的功能是在底层CPP文件.java层仅仅操作和更新一些界面(GUI),Java调用JNI实现功能.Java app基本核心,通过方法回调实现a类和b类方法.b类调a类方法信息交互相互控制融为一体.App实现一些JNI接口终于实现核心功能是cpp文件,最后通过Service类(耗时操作

3-13 用户模块与JWT集成

jwt的依赖包 复制到我们的父工程里. 改完版本后,加载这些包 把这三个包复制到utils包下面 最后的版本号去掉,因为父工程里面已经有了. 复制提供好的类 token的期限. jwt的工具类 复制写好的类 两个比较重要的方法,就是加密数据的盐 前端会发一个randomKey来做验证. 根据userName和randomKey生成. 生成token 结束 原文地址:https://www.cnblogs.com/wangjunwei/p/12690749.html