drf框架中jwt认证,以及自定义jwt认证

drf框架中jwt认证,以及自定义jwt认证,第1张

概述drf框架中jwt 一.模块的安装 :http://getblimp.github.io/django rest framework jwt/ 他是个第三方的开源项目 :`pip install dj drf框架中jwt一.模块的安装

官方@H_502_6@:http://getblimp.github.io/django-rest-framework-jwt/

他是个第三方的开源项目

安装@H_502_6@:pip install djangorestframework-jwt@H_502_6@

使用自带@H_502_6@设定好的jwt

from django.urls import pathfrom rest_framework_jwt.vIEws import obtain_jwt_tokenurlpatterns = [    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()     #验证'''@H_502_6@

测试接口:post请求

"""postman发生post请求接口:http://API.luffy.cn:8000/user/login/数据:{	"username":"admin","password":"admin"}"""@H_502_6@
二.工作原理
"""jwt:Json web tokens 采用Json格式在web上传输的 认证字符串jwt字符串:头.载荷.签名头:公司基本信息、项目组基本信息、常规加密算法名载荷:用户信息、过期时间签名:头、载荷、秘钥{头信息字典,采用base64加密算法}.{载荷信息字典,采用base64加密(base64编码)}.{头加密串、载荷加密串、服务器秘钥,采用hs256加密算法}base64是可逆的hash256是不可逆加密我们一般只会将账号信息,过期时间放载荷里面,一般把密码什么重要信息丢签名里面"""@H_502_6@
三.三大认证authentication(账号认证)
"""系统:session认证rest_framework.authentication.SessionAuthenticationAJAX请求通过认证:cookie中要携带 sessionID、csrftoken,请求头中要携带 x-csrftoken第三方:jwt认证 rest_framework_jwt.authentication.JsONWebTokenAuthenticationAJAX请求通过认证:请求头中要携带 authorization,值为 jwt空格token自定义:基于jwt、其它1)自定义认证类,继承BaseAuthentication(或其子类),重写authenticate2)authenticate中完成	拿到认证标识 auth	反解析出用户 user	前两步 *** 作失败 返回None => 游客	前两步 *** 作成功 返回user,auth => 登录用户	注:如果在某个分支抛出异常,直接定义失败 => 非法用户"""@H_502_6@
permission(权限认证)
"""系统:1)AllowAny:允许所有用户,校验方法直接返回True2)IsAuthenticated:只允许登录用户	必须request.user和request.user.is_authenticated都通过3)IsAuthenticatedOrReadonly:游客只读,登录用户无限制	get、option、head 请求无限制	前台请求必须校验 request.user和request.user.is_authenticated4)IsadminUser:是否是后台用户	校验 request.user和request.user.is_staff    is_staff(可以登录后台管理系统的用户)	自定义:基于auth的Group与Permission表1)自定义权限类,继承BasePermission,重写has_permission2)has_permission中完成	拿到登录用户 user <= request.user	校验user的分组或是权限	前两步 *** 作失败 返回False => 无权限	前两步 *** 作成功 返回True => 有权限"""@H_502_6@
throttle(访问频率)
"""系统: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、wait2)scope与settings.py的DEFAulT_THRottLE_RATES配合使用3)get_cache_key中完成	拿到限制信息 IDent <= request中获取	没有限制信息 返回None => 不限制	有限制信息 返回限制信息字符串 => 有限制"""@H_502_6@
四.自定义认证,基于jwt

其实就是在jwt的源码基础上进行相关的修改@H_502_6@

最简单的修改

from rest_framework.exceptions import AuthenticationFailedimport jwtfrom rest_framework_jwt.authentication import BaseJsONWebTokenAuthenticationfrom rest_framework_jwt.authentication import jwt_decode_handlerfrom rest_framework.authentication import BaseAuthenticationdef authenticate(self,request):    auth = 从request中得到    user = 从auth中得到    if not user:        return None    return user,auth@H_502_6@

如果我们自定制了一个权限我们进行全局设置必须自己在setting把这个函数加进去@H_502_6@

REST_FRAMEWORK = {'DEFAulT_AUTHENTICATION_CLASSES': [    	# django默认session校验:校验规则 游客 及 登录用户        # 'rest_framework.authentication.SessionAuthentication',# 'rest_framework.authentication.BasicAuthentication',# 'rest_framework_jwt.authentication.JsONWebTokenAuthentication',],}@H_502_6@

我们做局部设置就在我们自定义的类中添加@H_502_6@

authentication_classes = [我们自定义认证函数的对象]@H_502_6@
五.自定义权限相关

也是改源码@H_502_6@

"""系统:1)AllowAny:允许所有用户,校验方法直接返回True2)IsAuthenticated:只允许登录用户	必须request.user和request.user.is_authenticated都通过3)IsAuthenticatedOrReadonly:游客只读,登录用户无限制	get、option、head 请求无限制	前台请求必须校验 request.user和request.user.is_authenticated4)IsadminUser:是否是后台用户	校验 request.user和request.user.is_staff    is_staff(可以登录后台管理系统的用户)	自定义:基于auth的Group与Permission表1)自定义权限类,继承BasePermission,重写has_permission2)has_permission中完成	拿到登录用户 user <= request.user	校验user的分组或是权限	前两步 *** 作失败 返回False => 无权限	前两步 *** 作成功 返回True => 有权限"""@H_502_6@
#根据用户分组信息设置相关权限from rest_framework.permissions import BasePermissionclass 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@H_502_6@

如果我们自定制了一个权限全局设置我们必须自己在setting把这个函数加进去@H_502_6@

自定义类的路径API.authentications.JWTAuthentication@H_502_6@

#自定义一个权限from rest_framework.authentication import BaseAuthenticationfrom rest_framework.exceptions import AuthenticationFailedimport jwtfrom rest_framework_jwt.authentication import BaseJsONWebTokenAuthenticationfrom rest_framework_jwt.authentication import jwt_decode_handlerclass JWTAuthentication(BaseJsONWebTokenAuthentication):    # 自定义认证类,重写authenticate方法    def authenticate(self,request):        # 认证通过,返回user,auth        # 认证失败,返回None        auth = request.Meta.get('http_AUTH')  # 前台用auth携带token        if not auth:            return None        try:            payload = jwt_decode_handler(auth)        # 出现jwt解析异常,直接抛出异常,代表非法用户,也可以返回None,作为游客处理        except jwt.ExpiredSignature:            raise AuthenticationFailed('token已过期')        except:            raise AuthenticationFailed('token非法')        user = self.authenticate_credentials(payload)        return (user,auth)@H_502_6@
REST_FRAMEWORK = {        'DEFAulT_AUTHENTICATION_CLASSES': [        # '我们自定义权限函数的路径','API.authentications.JWTAuthentication','DEFAulT_PERMISSION_CLASSES': [    # 'rest_framework.permissions.AllowAny',# 全局配置:一站式网站(所有 *** 作都需要登录后才能访问)    # 'rest_framework.permissions.IsAuthenticated',}@H_502_6@

我们做局部设置就在我们自定义的类中添加@H_502_6@

permission_classes = [我们自定义认证函数的对象]@H_502_6@
六.自定义访问次数设置
"""系统:1)AnonRateThrottle:对同一IP游客的限制2)UserRateThrottle:对同一IP登录用户的限制必须在settings.py中REST_FRAMEWORK = {'DEFAulT_THRottLE_RATES': {    'user': '10/min',# 游客一分钟可以访问3次}}在视图类中:class TempAPIVIEw(APIVIEw):	...	throttle_classes = [AnonRateThrottle,UserRateThrottle]自定义:基于auth的Group与Permission表1)自定义频率类,继承SimpleRateThrottle,重写get_cache_key,明确scope	SimpleRateThrottle已经帮我们实现了 allow_request、wait2)scope与settings.py的DEFAulT_THRottLE_RATES配合使用3)get_cache_key中完成	拿到限制信息 IDent <= request中获取	没有限制信息 返回None => 不限制	有限制信息 返回限制信息字符串 => 有限制"""@H_502_6@

自定义频率类:一分钟一个手机号只允许访问一次接口

from rest_framework.throttling import SimpleRateThrottleclass ThreeMinRateThrottle(SimpleRateThrottle):    scope = 'sms'    def get_cache_key(self,vIEw):        # 对手机号频率限制        IDent = request.data.get('mobile')        if not IDent:  # 为发现限制条件,返回None代表不进行频率限制            return None        return self.cache_format % {            'scope': self.scope,'IDent': IDent        }# settings.py REST_FRAMEWORK = {'DEFAulT_THRottLE_RATES': {    'user': '10/min',# 登录的用户一分钟可以访问10次 如果是    'anon': '3/min',# 游客一分钟可以访问3次    'sms': '1/min',#是我们自定义的,默认只提供user以及anon}}@H_502_6@
在视图层class UserListAPIVIEw(ListAPIVIEw):    throttle_classes = [我们自定义的方法路径]@H_502_6@

源码里关于时间的一段代码

    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)@H_502_6@

这里我们可以看出来是先/进行字符串切分然后取第一个字母@H_502_6@所有我们这边不一定用min代表分,只要开头是m即可

七.全局设置有效时间以及jwt的名称
import datetimeJWT_AUTH = {    'JWT_EXPIRATION_DELTA': datetime.timedelta(seconds=30000),#d到期时间    'JWT_AUTH_header_PREFIX': 'TOKEN',#我们传参数的时候开头自定义内容,注意点这里必须与下面的token中以宫格隔开}@H_502_6@

源码中为@H_502_6@

USER_SETTINGS = getattr(settings,'JWT_AUTH',None)  #他是通过JWT_AUTH这个名字......'JWT_EXPIRATION_DELTA': datetime.timedelta(seconds=300),'JWT_AUTH_header_PREFIX': 'JWT',系统默认以jwt开头@H_502_6@
八.关于jwt自定制获取token

源码在rest_framework_jwt.seriallizers.py中@H_502_6@JsONWebTokenSerializer类

payload = jwt_payload_handler(user)return {    'token': jwt_encode_handler(payload),'user': user}@H_502_6@

我们如果自定义有几个关键点把握就好了一个是jwt_payload_handler@H_502_6@的方法

一个是 user对象

所有如果我们要在登入的时候抛出token

import refrom utils.response import APIResponsefrom rest_framework_jwt.serializers import jwt_encode_handler,jwt_payload_handlerclass LoginJWTAPIVIEw(APIVIEw):    authentication_classes = ()    permission_classes = ()    def post(self,*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        })@H_502_6@
九.有效期设置
# settings.py # jwt配置import datetimeJWT_AUTH = {    'JWT_EXPIRATION_DELTA': datetime.timedelta(seconds=30000),'JWT_AUTH_header_PREFIX': 'TOKEN',}@H_502_6@
总结

以上是内存溢出为你收集整理的drf框架中jwt认证,以及自定义jwt认证全部内容,希望文章能够帮你解决drf框架中jwt认证,以及自定义jwt认证所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/1223005.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-05
下一篇 2022-06-05

发表评论

登录后才能评论

评论列表(0条)