上节回顾
# 1 认证类的执行流程---》源码分析
-请求进来---》路由匹配成功----》执行path('test/', view.BookView.as_view()),--->继承了APIView----》APIView的as_view()内部的闭包函数view----》这个view中执行了self.dispatch--->APIView的dispatch----》
def dispatch(self, request, *args, **kwargs):
# 包装了新的request
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。。。。
今日内容
1 接口文档
# 前后端分离
-我们做后端,写接口
-前端做前端,根据接口写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自动生成接口文档步骤
- 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
# 接口文档,需要有的东西
-描述
-地址
-请求方式
-请求编码格式
-请求数据详解(必填,类型)
-返回格式案例
-返回数据字段解释
-错误码
2 jwt介绍和原理
# cookie session token 发展史
# Json web token (JWT) 就是web方向token的使用
#JWT的构成 三部分,每部分用 . 分割
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9.TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQ
- 头:header
声明类型,这里是jwt
声明加密的算法 通常直接使用 HMAC SHA256
公司信息。。。
-荷载:payload
-存放有效信息的地方
-过期时间
-签发时间
-用户id
-用户名字。。。
-签名:signature
-第一部分和第二部分通过秘钥+加密方式得到的
# jwt开发重点
-登录接口---->签发token
-认证类-----》jwt认证
# 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)
3 drf-jwt快速使用
#django+drf 平台开发jwt这套,有两个模块
-djangorestframework-jwt ---》一直可以用
-djangorestframework-simplejwt---》公司用的多---》希望你们试一下
-自己封装jwt签发和认证
# 使用步骤
- 1 安装
- 2 快速签发token---》登录接口,路由中配置
path('login/', obtain_jwt_token),
-3 postman,向http://127.0.0.1:8000/login/发送post请求,携带username和password
4 定制返回格式
# 以后,如果是基于auth的User表签发token,就可以不自己写了,但是登录接口返回的格式,只有token,不符合公司规范
# 使用步骤
1 写个函数:jwt_response_payload_handler
def jwt_response_payload_handler(token, user=None, request=None):
return {
'code': 100,
'msg': '登录成功',
'token': token,
'username': user.username
# 'icon':user.icon
}
2 配置一下 ,项目配置文件
JWT_AUTH = {
'JWT_RESPONSE_PAYLOAD_HANDLER': 'app01.utils.jwt_response_payload_handler',
}
3 使用postman测试,就能看到返回的格式了
5 jwt的认证类
# 以后接口要登录后才能访问的使用
1 在视图类上加一个认证类,一个权限类class BookView(ViewSetMixin, RetrieveAPIView):
authentication_classes = [JSONWebTokenAuthentication]
permission_classes = [IsAuthenticated] # 登录用户有权限,不登录用户没权限
2 postman测试
-请求头中key值叫Authorization
-请求头的value值是: jwt 有效的token值
作业
1 自动生成接口文档试一下
2 使用drf-jwt快速签发和认证token,定制返回格式
-----------
3 使用simplejwt,签发token
4 drf-jwt 登录接口怎么写的
-它把逻辑写在了序列化类中----》全局钩子中
标签:day09,request,self,jwt,接口,---,token,drf
From: https://www.cnblogs.com/tengyifan888/p/17105262.html