drf学习-10

一、昨日回顾

内置的认证、权限、频率类

  -认证类,可以返回两种结果,返回元组,返回None

  -权限类:IsAuthenticated,只要登录就有权限

  -频率类

    -SimpleRateThrottle

    -AnonRateThrottle:以ip地址限制

      把它配置在视图类上,去配置文件中配置:anon

    -UserRateThrottle:以用户id限制

      -把它配置在视图类上,去配置文件中配置

django中配置文件各个配置项的作用

过滤的使用

  -restful规范规定了,请求地址中带过滤条件(排序,分页)

  -查询所有接口

  -三种方式

    -使用内置的过滤类:SearchFilter,配置在视图类上,配置过滤的字段  /search=条件

    -django-filter第三方过滤类djangoFileterBackend,过滤字段:fliterset_fields = 【‘name’,publish】  /name=xxx&publish=yyy   

and条件的准确匹配

    -自定义过滤类

      -写一个类,继承BaseFileterBcakend,重写filter_queryset,在里面实现过滤,返回过滤后qs对象

接口文档的编写

  -前后端分离,两拨人写项目

  -写接口文档:

    -word,md

    -第三方平台:公司使用开源软件搭建的,公司自己开发,网上收费的

    -自动生成:swagger,corapi

全局异常

  -只要(路由匹配成功后,视图类的方法执行完)出了异常,都会被捕获,捕获后会执行一个函数,这个函数只处理了drf的异常,django的异常没有处理

  -自定义一个函数,出异常后,执行了咱们的函数

二、今日内容

1、cookie,session,token介绍

token分为三段式

  第一段:头:公司信息,加密方式。。。   打印出来{}

  第二段:荷载,真正的数据{name:curry,id:1}

  第三段:签名,通过第一段和第二段,通过某种加密方式加密得到的随机字符串

token的使用分两个阶段

  -登录成功后的【签发token阶段】——生成三段

  -登录成功访问某个接口的【验证阶段】——验证token是否合法

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

session是:存在于服务端的键值对

token是:三段式,服务端生成的,存放在客户端(浏览器就放在cookie中,移动端:存放在移动端中)

使用token的认证机制,服务端还要存数据吗?

token是服务的生成,客户端保存。服务的不存储token

更多知识点https://www.cnblogs.com/liuqingzheng/p/8990027.html

2、jwt原理介绍

# jwt(Jason Web Token), Token应用于web方向称之为jwt

# 构成:有头、荷载、签名构成
    -其实就是一段字符串,有三部分信息构成,然后将这个三部分用.链接到一起就构成了jwt字符串,eg:
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9.TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQ

# heard:头
    -声明类型:jwt
    -声明加密的算法, 通常直接使用 HMAC SHA256 ,也可以不用声明
    -公司信息
    {'typ':'jwt', 'alg':'HS256'...}
然后通过base64的编码就会变成一段字符串
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9

# payload:荷载
        -exp: jwt的过期时间,这个过期时间必须要大于签发时间
        -iat: jwt的签发时间
       - 用户信息: 用户信息
       {'exp':'123456', 'name':'lqz', 'id',2} 
然后通过base64的编码就会变成一段字符串
eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9

# signature:签名
    把头和荷载编码之后 在将它们两个加密后得到:
TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQ

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

# jwt最核心的就是
    -签发:登入接口签发
    -认证:认证类认证

session的认证机制

jwt的认证机制

jwt认证机制是最快的 因为jwt是直接在代码中直接签发和认证不用去数据库中读取

3、base64编码和解码

base64 可以把字符串编码成base64的编码格式:(大小写字母,数字和 =)eyJzdWIiOiAiMTIzNDU2Nzg5MCIsICJuYW1lIjogImxxeiIsICJhZG1pbiI6IHRydWV9

base64可以把base64编码的字符串,解码回原来的格式

应用场景:
    - jwt中使用
    - 网络中传输字符串就可以使用base64编码
    - 网络中传输图片,也可能使用base64的编码

编码

import base64
import json

d = {'name': 'jason', 'password': 123}
res = json.dumps(d)
print(res)

info = base64.b64encode(res.encode('utf8'))
print(info)  # eyJuYW1lIjogImphc29uIiwgInBhc3N3b3JkIjogMTIzfQ==
# 这样就是把json格式的字符串编码成了base的编码格式
解码

info_decode = base64.b64decode(info)
print(info_decode)  # b'{"name": "jason", "password": 123}'

d1 = json.loads(info_decode)  # 再通过json转换成python的字典即可
print(d1)  # {'name': 'jason', 'password': 123}

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}
    
    
# 固定写法:写一个函数,函数返回什么,前端就看到什么,配置在配置文件中

# 使用步骤:
	-1 写一个函数
    def jwt_response_payload_handler(token, user=None, request=None):
        return {
            'code':100,
            'msg':'登录成功',
            'username':user.username,
            'token':token
        }
     -2 把函数配置在配置文件中
        JWT_AUTH={
        'JWT_RESPONSE_PAYLOAD_HANDLER': 'app01.response.jwt_response_payload_handler',
    	}
        
 # 以后登录接口返回的格式就是咱们写的函数的返回值

6、自定义user表,签发token

# models.py 中定义UserInfo表

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('用户名或密码错误')
posted @ 2022-10-12 22:15  初学者-11  阅读(72)  评论(0编辑  收藏  举报