drf之day10:cookie,session,token,jwt原理介绍,base64编码与解码,drf修改返回格式,自定义user表,签发token

一:cookie,session,token介绍

1.cookie

存在在客户端浏览器的键值对

2.session

存在在服务端上的键值对

3.token
1.总结:

三段式,服务端生成(服务端不需要保存),客户端存放(浏览器的话:存放还cookie中,移动端:存放在指定的地方)

2.三段式:
  • 第一段:头:公司信息,加密方式等 {}
  • 第二段:荷载:真正的数据,例如: {name: ‘xxx’, id:1}
  • 第三段:签名:把第一段和第二段,通过某种加密(密钥加盐)方式得到得到
3.token的使用分为两个阶段
  • 签发阶段(登录成功后):生成三段
  • 验证阶段(登录成功后访问某个接口):验证token是否合法

二:jwt原理介绍

1.定义相关:

Json web token(JWT), token应用于web方向称之为jwt

2.构成和工作原理

JWT就是一段字符串,由三段信息构成的,将这三段信息文本用’.'链接在一起,就构成了jwt字符串

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9.TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQ
1.header:头
声明类型:这里是jwt
声明加密算法:通常直接使用:HMAC  SHA256
公司信息
{
   'typ': 'JWT',
   'alg': 'HS256'
}
由上面变成base64编码:eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9
2.payload:荷载
exp:jwt的过期时间, 必须大于签发时间
iat: jwt的签发时间
用户信息:用户信息
 {
    "exp": "1234567890",
    "name": "John Doe",
    "userid": 3
}
 由上面变成base64编码:eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9
3.signature:签发
把头和荷载加密后得到的:TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQ
4.secret
保存在服务端的(加密方式+盐),jwt的签发  生成也是在服务端的,secret就是用来进行jwt的签发和验证的,所以,它就是服务端的私钥,在任何场景都不应该流露出去,一旦客户端得到这个secret,那么客户端就可以自我签发jwt了
5.jwt使用流程核心
# 1.签发:登录接口签发
# 2.认证:认证类认证

三:base64编码和解码

1.功能:
# 1.base64 可以把字符串编码成base64的编码格式:(大小写字母,数字和 =)
# 2.base64可以把base64编码的字符串,解码回原来的格式eyJzdWIiOiAiMTIzNDU2Nzg5MCIsICJuYW1lIjogImxxeiIsICJhZG1pbiI6IHRydWV9
2.应用场景
  • jwt中使用
  • 网络中传输字符串就可以使用base64编码
  • 网络中传输图片,也可能使用base64的编码
3.编码
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)  # eyJuYW1lIjogImxxeiIsICJ1c2VyaWQiOiA2LCAiYWdlIjogMTl9
4.解码
# 把图片保存起来看看
res=base64.b64decode(s)
with open('code.png','wb') as f:
    f.write(res)
四:drf-jwt的快速使用
1.django中使用jwt
# 可以自己写:
-https://github.com/jpadilla/django-rest-framework-jwt  (比较老)
-https://github.com/jazzband/djangorestframework-simplejwt (比较新)
2.-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串
    

五:drf-jwt修改返回格式

1.原始的返回格式:
# 登录成功后,前端看到的格式,太固定了,只有token,我们想做成
{code:100,msg:'登录成功',token:adfasdfasdf}
2.修改返回格式
  • 第一步:写一个函数,函数返回什么,前端就看到什么

  •  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.response.jwt_response_payload_handler',
        	}
    
  • 第三步:以后登录接口返回的格式就是咱们写的函数的返回值

六:自定义user表,签发token

models.py

class UserInfo(models.Model):
    username = models.CharField(max_length=32)
    password = models.CharField(max_length=32)

写一个登录接口

from rest_framework.exceptions import APIException

from rest_framework_jwt.settings import api_settings
jwt_payload_handler = api_settings.JWT_PAYLOAD_HANDLER
jwt_encode_handler = api_settings.JWT_ENCODE_HANDLER


from .models import UserInfo
class UserView(APIView):
    def post(self, request):
        try:
            username = request.data.get('username')
            password = request.data.get('password')
            user=UserInfo.objects.get(username=username,password=password)
            # 根据user,签发token---》三部分:头,荷载,签名
            # 使用djagnorestframework-jwt模块提供的签发token的函数,生成token
            payload = jwt_payload_handler(user) # 通过user对象---》{username:lqz,id:1,过期时间}
            token=jwt_encode_handler(payload) # 根据payload---》得到token:头.荷载.签名
            print(payload)
            print(token)

            return Response({'code':100,'msg':'登录成功','token':token})
        except Exception as e:
            raise APIException('用户名或密码错误')
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值