drf框架中jwt认证,以及自定义jwt认证
0909自我总结
drf框架中jwt
一.模块的安装
官方
:
他是个第三方的开源项目
安装
:pip install djangorestframework-jwt
使用自带
设定好的jwt
from django.urls import path from rest_framework_jwt.views import obtain_jwt_token urlpatterns = [ path('login/', obtain_jwt_token), ] ''' path('login/', obtain_jwt_token)其实相当于path('login/', obtainjsonwebtoken.as_view()) 因为我们之间进源码可以看到 obtain_jwt_token = obtainjsonwebtoken.as_view() #获得 refresh_jwt_token = refreshjsonwebtoken.as_view() #刷新 verify_jwt_token = verifyjsonwebtoken.as_view() #验证 '''
测试接口:post请求
""" postman发生post请求 接口:http://api.luffy.cn:8000/user/login/ 数据: { "username":"admin", "password":"admin" } """
二.工作原理
""" jwt:json web tokens 采用json格式在web上传输的 认证字符串 jwt字符串:头.载荷.签名 头:公司基本信息、项目组基本信息、常规加密算法名 载荷:用户信息、过期时间 签名:头、载荷、秘钥 {头信息字典,采用base64加密算法}.{载荷信息字典,采用base64加密算法}.{头加密串、载荷加密串、服务器秘钥,采用hs256加密算法} base64是可逆加密 hash256是不可逆加密 我们一般只会将账号信息,过期时间放载荷里面,一般把密码什么重要信息丢签名里面 """
三.三大认证
session认证
系统自带的
rest_framework.authentication.sessionauthentication
ajax请求通过认证:
cookie中要携带 sessionid、csrftoken,请求头中要携带 x-csrftoken
jwt认证
第三方
与session认证区别他不用再去查sessionid
表,只要查user
表就可以了
rest_framework_jwt.authentication.jsonwebtokenauthentication
ajax请求通过认证:
请求头中要携带 authorization,值为 jwt空格token
基于jwt、其它
自定义
1)自定义认证类,继承baseauthentication(或其子类),重写authenticate
2)authenticate中完成
拿到认证标识 auth
反解析出用户 user
前两步操作失败 返回none => 游客
-
前两步操作成功 返回user,auth => 登录用户
注
:如果在某个分支抛出异常,直接定义失败 => 非法用户
四.自定义认证,基于jwt
其实就是在jwt的源码基础上进行相关的修改
最简单的修改
from rest_framework.exceptions import authenticationfailed import jwt from rest_framework_jwt.authentication import basejsonwebtokenauthentication from rest_framework_jwt.authentication import jwt_decode_handler from rest_framework.authentication import baseauthentication def authenticate(self, request): auth = 从request中得到 user = 从auth中得到 if not user: return none return user, auth
如果我们自定制了一个权限我们进行全局设置必须自己在setting把这个函数加进去
'default_authentication_classes': [ '我们自定义认证函数的对象', ],
我们做局部设置就在我们自定义的类中添加
authentication_classes = [我们自定义认证函数的对象]
五.自定义权限相关
也是改源码
""" 系统: 1)allowany:允许所有用户,校验方法直接返回true 2)isauthenticated:只允许登录用户 必须request.user和request.user.is_authenticated都通过 3)isauthenticatedorreadonly:游客只读,登录用户无限制 get、option、head 请求无限制 前台请求必须校验 request.user和request.user.is_authenticated 4)isadminuser:是否是后台用户 校验 request.user和request.user.is_staff is_staff(可以登录后台管理系统的用户) 自定义:基于auth的group与permission表 1)自定义权限类,继承basepermission,重写has_permission 2)has_permission中完成 拿到登录用户 user <= request.user 校验user的分组或是权限 前两步操作失败 返回false => 无权限 前两步操作成功 返回true => 有权限 """
#根据用户分组信息设置相关权限 from rest_framework.permissions import basepermission class adminpermission(basepermission): # 继承basepermission,重写has_permission def has_permission(self, request, view): # 有权限,返回true # 无权限,返回false user = request.user if not user: return false # 用户是 管理员 分组 (管理员分组是group表中的一条自定义记录) if not user.groups.filter(name='管理员'): return false # 登录的用户必须是自定义管理员分组成员 return true
如果我们自定制了一个权限全局设置我们必须自己在setting把这个函数加进去
'default_permission_classes': [ '我们自定义权限函数的路径', ],
我们做局部设置就在我们自定义的类中添加
permission_classes = [我们自定义认证函数的对象]
六.自定义访问次数设置
""" 系统: 1)anonratethrottle:对同一ip游客的限制 2)userratethrottle:对同一ip登录用户的限制 必须在settings.py中 'default_throttle_rates': { 'user': '10/min', # 登录的用户一分钟可以访问10次 'anon': '3/min', # 游客一分钟可以访问3次 } 在视图类中: class tempapiview(apiview): ... throttle_classes = [anonratethrottle, userratethrottle] 自定义:基于auth的group与permission表 1)自定义频率类,继承simpleratethrottle,重写get_cache_key,明确scope simpleratethrottle已经帮我们实现了 allow_request、wait 2)scope与settings.py的default_throttle_rates配合使用 3)get_cache_key中完成 拿到限制信息 ident <= request中获取 没有限制信息 返回none => 不限制 有限制信息 返回限制信息字符串 => 有限制 """
自定义频率类:一分钟一个手机号只允许访问一次接口
from rest_framework.throttling import simpleratethrottle class threeminratethrottle(simpleratethrottle): scope = 'sms' def get_cache_key(self, request, view): # 对手机号频率限制 ident = request.data.get('mobile') if not ident: # 为发现限制条件,返回none代表不进行频率限制 return none return self.cache_format % { 'scope': self.scope, 'ident': ident } # settings.py 'default_throttle_rates': { 'user': '10/min', # 登录的用户一分钟可以访问10次 如果是 'anon': '3/min', # 游客一分钟可以访问3次 'sms': '1/min', #是我们自定义的,默认只提供user以及anon }
在视图层 class userlistapiview(listapiview): throttle_classes = [我们自定义的方法路径]
源码里关于时间的一段代码
def parse_rate(self, rate): """ given the request rate string, return a two tuple of: <allowed number of requests>, <period of time in seconds> """ if rate is none: return (none, none) num, period = rate.split('/') num_requests = int(num) duration = {'s': 1, 'm': 60, 'h': 3600, 'd': 86400}[period[0]] return (num_requests, duration)
这里我们可以看出来是先/进行字符串切分然后取第一个字母
所有我们这边不一定用min代表分,只要开头是m即可
七.全局设置有效时间以及jwt的名称
import datetime jwt_auth = { 'jwt_expiration_delta': datetime.timedelta(seconds=30000),#d到期时间 'jwt_auth_header_prefix': 'token', #我们传参数的时候开头自定义内容,注意点这里必须与下面的token中以宫格隔开 }
源码中为
user_settings = getattr(settings, 'jwt_auth', none) #他是通过jwt_auth这个名字 ...... 'jwt_expiration_delta': datetime.timedelta(seconds=300), 'jwt_auth_header_prefix': 'jwt', 系统默认以jwt开头
八.关于jwt自定制获取token
源码在rest_framework_jwt.seriallizers.py中
jsonwebtokenserializer类
payload = jwt_payload_handler(user) return { 'token': jwt_encode_handler(payload), 'user': user }
我们如果自定义有几个关键点把握就好了一个是jwt_payload_handler
的方法
一个是 user对象
所有如果我们要在登入的时候抛出token
class loginjwtapiview(apiview): authentication_classes = () permission_classes = () def post(self, request, *args, **kwargs): # username可能携带的不止是用户名,可能还是用户的其它唯一标识 手机号 邮箱 username = request.data.get('username') password = request.data.get('password') # 如果username匹配上手机号正则 => 可能是手机登录 if re.match(r'1[3-9][0-9]{9}', username): try: # 手动通过 user 签发 jwt-token user = models.user.objects.get(mobile=username) except: return apiresponse(1, '该手机未注册') # 邮箱登录 等 # 账号登录 else: try: # 手动通过 user 签发 jwt-token user = models.user.objects.get(username=username) except: return apiresponse(1, '该账号未注册') # 获得用户后,校验密码并签发token if not user.check_password(password): return apiresponse(1, '密码错误') payload = jwt_payload_handler(user) token = jwt_encode_handler(payload) return apiresponse(0, 'ok', results={ 'username': user.username, 'mobile': user.mobile, 'token': token })
上一篇: 在React中写一个Animation组件,为组件进入和离开加上动画/过度
下一篇: 分布式架构心得
推荐阅读
-
YII2框架中自定义用户认证模型,完成登陆和注册操作示例
-
drf框架中jwt认证,以及自定义jwt认证
-
浅谈ASP.NET Core 中jwt授权认证的流程原理
-
利用go-zero在Go中快速实现JWT认证的步骤详解
-
ASP.Net Core3.0中使用JWT认证的实现
-
springboot+sercuity+oauth2+Jwt+手机号+微信+密码 企业级认证与授权原理以及实现(完整版)
-
hrm中的jwt认证:需求分析与用户登录
-
OAuth2 和 SpringSecurity完成授权认证中心(二) 通过jwt令牌,以及JDBC存储
-
开源干货!!!.NET Core + JWT令牌认证 + Vue.js(iview-admin) 通用动态权限(RBAC)管理系统框架[DncZeus]开源啦!!!
-
drf框架中认证与权限工作原理及设置