官方@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即可
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认证所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)