drf jwt 原理,cookie,session,token base64
文章目录
- drf jwt 原理,cookie,session,token base64
- 1、cookie,session,token介绍
- 2、jwt 原理介绍
- 3、 base64编码和解码
- 4、drf-jwt快速使用
- 5、drf-jwt 修改返回格式
- 5.1、使用步骤
- 6、自定义user表,签发token
- 作业
1、cookie,session,token介绍
摘自
token:三段式
第一段:头:公司信息,加密方式
第二段:荷载:真正的数据{name:ming,id:1}
第三段:签名,通过第一段和第二段,通过某种加密方式加密得到 字符码
token的使用分两个阶段
登录成功后的【签发token阶段】—>生成三段
登录成功访问某个接口的 【验证阶段】—>验证token是否合法
cookie是:存在客户端浏览器的键值对
session是:存在于服务端键值对
token是:三段式,服务端生成的,存放在客户端(浏览器就放在cookie中,移动端:存在移动端中)
使用token的认证机制,服务端还要存数据吗?token是服务的生成,客户端保存,服务的不存储token
2、jwt 原理介绍
Json web token (JWT),token的应用于web方向的称之为jwt
构成和工作原理
Jwt 就是一段字符串,由三段信息构成的,将三段信息文本用,链接一起就构成了jwt字符串。就像这个样eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9.TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQ
header:头
声明类型,这里是jwt
声明加密的算法:通常直接使用 HMAC SHA256
公司信息
由
{'typ': 'JWT','alg': 'HS256'
}
变成了(base64的编码)
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9
payload:荷载
exp:jwt的过期时间,这个过期时间必须要大于签发时间
iat:jwt的签发时间
用户信息:用户信息
由
{"exp": "1234567890","name": "John Doe","userid": 3}
变成了(base64的编码)
eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9
signature: 签名
把头和荷载加密后得到的:TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQ
注意:secret是保存在服务器端的(加密方式+盐),jwt的签发生成也是在服务器端的,secret就是用来进行jwt的签发和jwt的验证,所以,它就是你服务端的私钥,在任何场景都不应该流露出去。一旦客户端得知这个secret, 那就意味着客户端是可以自我签发jwt了
jwt 使用流程最核心的是:
签发:登录接口签发
认证:认证类认证
3、 base64编码和解码
base64 可以把字符串编码成base64的编码格式:(大写字母,数字和=)
eyJzdWIiOiAiMTIzNDU2Nzg5MCIsICJuYW1lIjogImxxeiIsICJhZG1pbiI6IHRydWV9
base64 可以把base64 编码的字符串,解码回原来的格式
应用场景:
jwt中使用
网络中传输字符串就可以使用base64编码
网络中传输图片,也可能使用base64的编码
编码解码
import json
import base64
d = {'name': 'lqz', 'userid': 6, 'age': 19}
info = json.dumps(d)
print(info)
# 把字符串使用base64编码
res=base64.b64encode(info.encode('utf-8'))
print(res) # eyJuYW1lIjogImxxeiIsICJ1c2VyaWQiOiA2LCAiYWdlIjogMTl9res=base64.b64decode(s)
with open('code.png','wb') as f:f.write(res)
4、drf-jwt快速使用
jwt:签发(登录接口)认证(认证类)
django中使用jwt
可以自己写
https://github.com/jpadilla/django-rest-framework-jwt(比较老)
https://github.com/jazzband/djangorestframework-simplejwt (比较新
安装
pip3 install djangorestframework-jwt
快速使用
-
迁移表,因为它默认使用auth的user表签发token
-
创建超级用户(auth的user表中要有记录)
-
咱们不需要写登录接口了,如果是使用auth的user表作为用户表,它可以快速蒸发
-
签发(登录):只需要咋路由中配置(因为它邦咱们写好登录接口了)
from rest_framework_jwt.views import obtain_jwt_token urlpatterns = [path('login/',obtain_jwt_token), ]
认证(认证类):导入,配置在视图上
class TestView(APIView):authentication_classes = [JSONWebTokenAuthentication,]permission_classes = [IsAuthenticated,]
前端访问时,token需要放在请求头中
Authorization:jwt token串
5、drf-jwt 修改返回格式
登录成功后,前端看到格式,太固定了,只有token,我们想做成
{code:100,msg:'登录成功',token:adfasdfasdf}
固定写法:写一个函数,函数返回什么,前端就看到什么,配置在配置文件中
5.1、使用步骤
写一个函数
def jwt_response_payload_handler(token, user=None, request=None):return {'code':100,'msg':'登录成功','username':user.username,'token':token}
把函数配置在配置文件中
JWT_AUTH={'JWT_RESPONSE_PAYLOAD_HANDLER':'app01.jwt_response.jwt_response_payload_handler'
}
以后登录接口返回的格式就是咱们写的函数的返回值
6、自定义user表,签发token
自己写 userinfo表
class User(models.Model):username = models.CharField(max_length=32)password = models.CharField(max_length=32)
写一个登录接口
from rest_framework.exceptions import APIException
from app01.models import User
from rest_framework_jwt.settings import api_settingsjwt_payload_handler = api_settings.JWT_PAYLOAD_HANDLER
jwt_encode_handler = api_settings.JWT_ENCODE_HANDLER
class UserView(APIView):def post(self,request):username =request.data.get('username')password = request.data.get('password')try:user=User.objects.get(username=username,password=password)#根据user,签发token>>>三部分:头,荷载,签名# 使用djagnorestframework-jwt模块提供的签发token的函数,生成token# 通过user对象---》{username:lqz,id:1,过期时间}payload = jwt_payload_handler(user)# 根据payload---》得到token:头.荷载.签名token = jwt_encode_handler(payload)return Response({'code':100,'msg':'登录成功','token':token})except :raise APIException('用户名或密码错误')
作业
-
快速签发
-
修改登录返回格式
-
自定义用户表签发token
aming\Typora\typora-user-images\image-20221012161242878.png)] -
自定义认证类,验证token(尽量写)