首页 > 其他分享 >接口文档 jwt介绍和原理 drf-jwt快速使用 定制返回格式 jwt认证类

接口文档 jwt介绍和原理 drf-jwt快速使用 定制返回格式 jwt认证类

时间:2023-02-09 23:00:42浏览次数:47  
标签:request self base64 jwt --- token 文档 drf

目录

回顾

# 认证类的执行流程 ---> 源码分析
	请求进来 ---> 路由匹配成功 ---> 执行path('test/', view.BookView.as_view()), ---> 继承了APIView ---> APIView的as_view()内部的闭包函数view ---> 这个view中执行了self.dispatch ---> APIView的dispatch ---> 这个view中执行了self.dispatch ---> APIView的dispatch --->
  def dispatch(self, request, *args, **kwargs):
    # 包装了新的requset
 request = self.initialize_request(request, *args, **kwargs)
        。。。
        # 执行3大认证
        self.initial(request, *args, **kwargs)
        # 下面执行视图类的方法
    def initial(self, request, *args, **kwargs):
        # 认证
        self.perform_authentication(request)
        self.check_permissions(request)
        self.check_throttles(request)
	def perform_authentication(self, request):
        request.user
 	####### Request 新的Request内部找  user
    @property
    def user(self):
        if not hasattr(self, '_user'):
            with wrap_attributeerrors():  # 上下文管理器----》面试
                self._authenticate()
        return self._user
   ### 核心代码
    def _authenticate(self):
        # self.authenticators---》列表[认证类对象1,认证类对象2]
        # authenticator 是认证类的对象
        for authenticator in self.authenticators:
            try:
                #认证类对象.authenticate   self 是新的request对象
                user_auth_tuple = authenticator.authenticate(self)
            except exceptions.APIException:
                self._not_authenticated()
                raise

            if user_auth_tuple is not None:
                self._authenticator = authenticator
                #self 是新的request
                # request.user 就是当前登录用户
                # request.auth 一般把token给它
                self.user, self.auth = user_auth_tuple
                return
        self._not_authenticated()
        
  # self.authenticators:是什么时候传入的?执行__init__ 就是在Request初始化的时候传入的
	-在APIView的dispatch的self.initialize_request(request, *args, **kwargs)初始化的,
     return Request(
            request,
            parsers=self.get_parsers(),
         	#在这里传入的
            authenticators=self.get_authenticators(),
            negotiator=self.get_content_negotiator(),
            parser_context=parser_context
        )
    -APIView的--get_authenticators()----》return [auth() for auth in self.authentication_classes]
    
    -self.authentication_classes:视图类中配置的一个个的认证类的列表,如果没配,配置文件中,内置配置文件中
    

# 2 权限类的执行流程



# 3 频率类的执行流程

# 4 自己定义了一个频率类,基于BaseThrottle,重写allow_request

# 5 SimpleRateThrottle
	-继承它,写代码少
    -只需要重写get_cache_key和scope类属性,配置文件配置
    -源码:allow_request----》就是咱们上面写的,可扩展性高,好多东西从配置文件取的
    
    
    
# 6 全局异常处理
	-源码中,在3大认证,视图类的方法中如果出错,就会执行:self.handle_exception(exc)
     def handle_exception(self, exc):
        # 去配置文件中找到:EXCEPTION_HANDLER对应的函数,exception_handler
        exception_handler = self.get_exception_handler()
        # exception_handler(exc,context)
        response = exception_handler(exc, context)
        return response
    
    
    -自己再配置文件中配置,以后出了异常,走咱们自己的,有两个参数exc, context
    	-exc错误对象
        -context:上下文,包含 view,request。。。。

接口文档

# 前后端分离
	-我们做后端,写接口
    -前端做前端,根据接口写app,pc,小程序
    
    -作为后端来讲,我们很清楚,比如登录接口  /api/v1/login/---->post---->username,password 编码方式json----》返回的格式  {code:100,msg:登录成功}
    
    
    -后端人员,接口写完,一定要写接口文档
    
    
# 接口文档如何编写
	-1 使用word,md 编写接口文档
  -2 使用第三方平台,编写我们的接口文档(非常多)---》收费
    	-https://www.showdoc.com.cn/item/index
  -3 公司自己使用第三方开源的搭建的---》Yapi ---》你如果想自己搭建
    	-https://zhuanlan.zhihu.com/p/366025001 
            
  -4 使用drf编写的接口,可以自动生成接口文档
    	-swagger---》drf-yasg---》官方推荐使用
        -coreapi----》咱们讲

coreapi的安装及使用

# 使用coreapi自动生成接口文档步骤
	- 1 安装 
  - 2 配置路由
        from rest_framework.documentation import include_docs_urls
        path('docs/', include_docs_urls(title='xx项目接口文档')),
  -3 在视图类,方法上,写注释即可
    	-在类上加注释
        -在类的方法上加注释
        -在序列化类或表模型的字段上加  help_text,required。。。。
    
    
  -4 配置文件配置
    	REST_FRAMEWORK = {
     		'DEFAULT_SCHEMA_CLASS': 'rest_framework.schemas.coreapi.AutoSchema',

    	}
        
        
   -5 访问地址:http://127.0.0.1:8000/docs
    
    
    
# 接口文档,需要有的东西
	-描述
    -地址
    -请求方式
    -请求编码格式
    -请求数据详解(必填,类型)
    -返回格式案例
    -返回数据字段解释
    -错误码

image-20230209220828771

jwt介绍和原理

# cookie session token 发展史

# Json web token (JWT)  就是web方向token的使用

介绍:

JWT认证:在用户注册或登录后,我们想记录用户的登录状态,或者为用户创建身份认证的凭证。我们不再使用Session认证机制,而使用Json Web Token(本质就是token)认证机制

构成和工作原理:

1.JWT的构成

JWT就是一段字符串,由三段信息构成的,将这三段信息文本用.链接一起就构成了Jwt字符串。就像这样:

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9.TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQ

第一部分我们称它为头部(header),第二部分我们称其为载荷(payload, 类似于飞机上承载的物品),第三部分是签证(signature).

2.JWT之header

jwt的头部承载两部分信息:

  • 声明类型 这里是jwt
  • 声明机密的算法,通常直接使用HMAC SHA256

完整的头部就像下面这样的JSON

{
  'typ': 'JWT',
  'alg': 'HS256'
}

然后将头部进行base64加密(该加密是可以对称解密的),构成了第一部分.

eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9

3.JWT之荷载(payload)

载荷就是存放有效信息的地方。这个名字像是特指飞机上承载的货品,这些有效信息包含三个部分

  • 标准中注册的声明
  • 公共的声明:公共的声明可以添加任何的信息,一般添加用户的相关信息或其他业务需要的必要信息.但不建议添加敏感信息,因为该部分在客户端可解密.
  • 私有的声明:私有声明是提供者和消费者所共同定义的声明,一般不建议存放敏感信息,因为base64是对称解密的,意味着该部分信息可以归类为明文信息

定义一个payload:

{
  "sub": "1234567890",
  "name": "John Doe",
  "admin": true
}

然后将其进行base64加密,得到JWT的第二部分

eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9

JWT之签证(signature)

JWT的第三部分是一个签证信息,这个签证信息由三部分组成

  • header (base64后的)
  • payload (base64后的)
  • secret

这个部分需要base64加密后的header和base64加密后的payload使用.连接组成的字符串,然后通过header中声明的加密方式进行加盐secret组合加密,然后就构成了jwt的第三部分。

// javascript
var encodedString = base64UrlEncode(header) + '.' + base64UrlEncode(payload);

var signature = HMACSHA256(encodedString, 'secret'); // TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQ

再者三部分用 . 连接成一个完整的字符串,构成了最终的jwt

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9.TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQ

PS:secret是保存在服务器端的,jwt的签发生成也是在服务器端的,secret就是用来进行jwt的签发和jwt的验证,所以,它就是你服务端的私钥,在任何场景都不应该流露出去。一旦客户端得知这个secret, 那就意味着客户端是可以自我签发jwt了

总结:

 -头:header
    	声明类型,这里是jwt
		声明加密的算法 通常直接使用 HMAC SHA256
        公司信息。。。
-荷载:payload
    	-存放有效信息的地方
        -过期时间
        -签发时间
        -用户id
        -用户名字。。。
-签名:signature
    	-第一部分和第二部分通过秘钥+加密方式得到的

image-20230209224456475

drf项目的jwt认证开发流程(重点)

1)用账号密码访问登录接口,登录接口逻辑中调用 签发token 算法,得到token,返回给客户端,客户端自己存到cookies中

2)校验token的算法应该写在认证类中(在认证类中调用),全局配置给认证组件,所有视图类请求,都会进行认证校验,所以请求带了token,就会反解出user对象,在视图类中用request.user就能访问登录的用户

注:登录接口需要做 认证 + 权限 两个局部禁用

补充base64编码解码

#  base64编码和解码

import base64
import json
# dic={'user_id':1,'username':"lqz"}
#
# dic_str=json.dumps(dic)
#
# #把这个字符串使用base64编码
# res=base64.b64encode(dic_str.encode('utf-8'))
# print(res)   #


# 注意:base64编码后,字符长度一定是4的倍数,如果不是,使用  =  补齐,  = 不表示数据
# 解码
res=base64.b64decode('TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQ=')
print(res)



# base64 应用场景
'''
1 jwt 使用了base64
2 网络中传输数据,也会经常使用 base64编码
3 网络传输中,有的图片使用base64编码

'''
s=''
res=base64.b64decode(s)
with open('a.png','wb') as f:
    f.write(res)

image-20230209203637938

drf-jwt快速使用

#django+drf 平台开发jwt这套,有两个模块
	-djangorestframework-jwt  ---》一直可以用
	-djangorestframework-simplejwt---》公司用的多---》自己试一下
    -自己封装jwt签发和认证
# 使用步骤
	- 1 安装
  from restframework_jwt.view import obtain_jwt_token
  - 2 快速签发token---》登录接口,路由中配置
    	path('login/', obtain_jwt_token),
  - 3 使用Django自带authuser表用createsuperuser创建超级用户插入一条数据
  - 4  postman,向http://127.0.0.1:8000/login/发送post请求,携带username和password

image-20230209203211658

返回结果

image-20230209203230108

定制返回格式

以后,如果是基于auth的User表签发token,就可以不用自己写了,但是登录接口返回的格式,只有token,不符合公司规范

# 使用规范
1 写个函数:jwt_response_payload_handler
def jwt_reponse_payload_hander(token,user=None):
  return {
    'code': 100,
    'msg': '登录成功',
    'token': user.username,
    'icon': user.icon
  }

2 配置一下,项目配置文件
JWT_AUTH = {
  'JWT_RESPONSE_PAYLOAD_HANDLER': 'app01.utils.jwt_response_payload_handler'
}

3 使用postman测试,login登录username, password就能看到返回的格式

image-20230209222013671

jwt的认证类

# 以后接口要登录后才能访问使用

	1 在视图类上加一个认证类,一个权限类class BookView(ViewSetMixin, RetrieveAPIView):
    	authentication_classes = [JSONWebTokenAuthentication]
    	permission_classes = [IsAuthenticated]  # 登录用户有权限,不登录用户没权限
	2 postman测试
    -请求头中key值叫Authorization
    -请求头的value值是:  jwt 有效的token值

image-20230209210616037

postman访问结果:

意思就是你带了token,带错了不行,没带反而可以

image-20230209211426386

这样就必须携带:请求头中key值叫Authorization,value值是: jwt 空格 有效的token值

image-20230209211542830

结果:

image-20230209212430860

标签:request,self,base64,jwt,---,token,文档,drf
From: https://www.cnblogs.com/xiao-fu-zi/p/17107435.html

相关文章

  • drf接口文档,jwt介绍和原理,drf_jwt快速使用,定制返回格式,jwt的认证类
    内容回顾认证类的请求执行流程—》源码分析请求进来》路由匹配》path('test/',view.BookView.as_view()),》继承了APIView》APIView中的as_view()内部的闭包函数view》......
  • drf 接口文档 jwt介绍和原理 drf-jwt快速使用 定制返回格式 jwt认证类
    昨日内容#1认证类的执行流程--->源码分析-请求进来--->路由匹配成功--->执行path('text/',view.BookView.as_view()),--->继承了APIView--->APIView的as_view()内部的......
  • drf-jwt、simplejwt的使用
    1.接口文档#前后端分离 -我们做后端,写接口-前端做前端,根据接口写app,pc,小程序-作为后端来讲,我们很清楚,比如登录接口/api/v1/login/---->post---->usern......
  • 接口文档 jwt介绍和原理 drf-jwt快速使用 定制返回格式
    今日内容总结接口文档#接口文档如何编写 -1使用word,md编写接口文档 -2使用第三方平台编写我们的接口文档(非常多)--->收费 -https://www.showdoc.com.......
  • 接口测试工具+drf安装与使用
    drf安装和简单使用#1、安装##安装pipinstalldjangorestframework2、使用#1.settings.py中INSTALLED_APPS=['rest_framework']2.在mod......
  • DRF - coreapi自动生成接口文档、JWT
    目录1接口文档1.什么是接口文档2.接口文档的编写方式3.使用coreapi自动生成接口文档步骤(1)安装coreapi(2)配置路由(3)文档说明文字:在视图类,方法上写注释即可(4)配置文件中配置自......
  • 接口文档、jwt介绍和原理、drf-jwt快速使用、定制返回格式、jwt的认证类
    接口文档、jwt介绍和原理、drf-jwt快速使用、定制返回格式、jwt的认证类drf-接口文档我们接口编写好了之后,就需要编写接口文档,给前端的人使用前端开发人员根据后端人员......
  • drf-jwt签发与认证
    jwt认证介绍和原理jwt介绍:Jsonwebtoken(JWT),是为了在网络应用环境间传递声明而执行的一种基于JSON的开放标准((RFC7519).该token被设计为紧凑且安全的,特别适用于分布......
  • 接口文档与JWT
    接口文档接口文档的作用在前后端分离的项目中,我们写完后端后,我们很清楚有哪些接口、属性、编码方式、返回格式等,但是做前端的不清楚,所以就需要我们编写接口文档,将这......
  • 接口文档和drf-jwt
    1接口文档#前后端分离 -我们做后端,写接口-前端做前端,根据接口写app,pc,小程序-作为后端来讲,我们很清楚,比如登录接口/api/v1/login/---->post--->usernam......