152-jwt的介绍及使用

昨日回顾

1 分页功能
	-三个类:普通分页,偏移分页,游标分页
    -每个类中都有几个属性:查询的字段,每页显示的条数,每页最多显示的条数,游标分页中有个排序
    -定义一个类,继承上面3个其中一个,重写字段
    -继承了APIView:实例化得到分页对象,把要分页的数据传入,返回分页后的数据,序列化,可以按照自己定制的规则返回,也可也使用page.get_paginated_response(ser.data)
    -如果继承了ListModelMixin和GenericAPIView,直接配置就可以了
    	pagination_class = MyCursorPagination
2 全局异常
	-写一个方法
    def common_exception_handler(exc, context):
        response = exception_handler(exc, context)
        if response is None:
            response = Response({'code': 999, 'detail': str(exc)}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
        return response
   	-setting中配置一下
    	'EXCEPTION_HANDLER':'app01.utils.common_exception_handler'
    -通常情况咱们会记录日志
    	-使用django日志记录  xx.log文件中
        -使用sentry(公司自己写)日志记录, 平台(django),查询,统计,告警
3 自己写的Response
	class APIResponse(Response):
        def __init__(self, code=100, msg='成功', data=None, status=None, headers=None, content_type=None, **kwargs):
            dic = {'code': code, 'msg': msg}
            if data:
                dic['data'] = data
            dic.update(kwargs) # 这里使用update
            super().__init__(data=dic, status=status,
                             template_name=None, headers=headers,
                             exception=False, content_type=content_type)
    #我们期望这种格式
    {
        code:100
        msg:成功,失败信息
        data:[]
        count:
    }
    # 使用
    APIResponse(data=[],code=101,heades={})
    
    
4 自动生成接口文档
	-手写
    -自动生成(drf:crorapi),swagger(java,go,python)
    	-安装:pip3 install coreapi
        -路由中配置:path('docs/', include_docs_urls(title='图书管理系统api')),
        -在配置文件中配置:'DEFAULT_SCHEMA_CLASS': 'rest_framework.schemas.coreapi.AutoSchema',
        -写视图类,在里面要加注释,就在接口平台就能看到
        
   	

# 作业:
1 自定义User表扩展auth的User,新增mobile唯一约束字段;新增icon图片字段
2 在自定义User表基础上,用 GenericViewSet + CreateModelMixin + serializer 完成User表新增接口(就是注册接口)(重要提示:序列化类要重写create方法,不然密码就是明文了)
3 在自定义User表基础上,用 GenericViewSet + RetrieveModelMixin + serializer 完成User表单查(就是用户中心)
4 在自定义User表基础上,用 GenericViewSet + UpdateModelMixin + serializer 完成用户头像的修改

今日内容

1 作业讲解之用户注册/查询用户/修改头像


4 jwt认证介绍

1 不再使用Session认证机制,而使用Json Web Token(本质就是token)认证机制,用户登录认证
2 用户只要登录了,返回用户一个token串(随机字符串),每次用户发请求,需要携带这个串过来,验证通过,我们认为用户登录了
3 JWT的构成(字符串)
	-三部分(每一部分中间通过.分割):header   payload  signature
    -header:明类型,这里是jwt,声明加密算法,头里加入公司信息...,base64转码
        {
          'typ': 'JWT',
          'alg': 'HS256'
        }
    -payload:荷载(有用),当前用户的信息(用户名,id,这个token的过期时间,手机号),base64转码
        {
          "sub": "1234567898",
          "name": "egon",
          "admin": true,
          "userid":1,
          'mobile':123444444
        }
    -signature:签名
    	-把前面两部分的内容通过加密算法+密钥加密后得到的一个字符串
        
        
    -jwt总的构成样子:
 	 eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9.TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQ
        
4 JWT认证原理
	-用户携带用户名,密码登录我的系统,校验通过,生成一个token(三部分),返回给用户---》登录功能完成
    -访问需要登录的接口(用户中心),必须携带token过来,后端拿到token后,把header和payload截出来,再通过一样的加密方式和密码得到一个signature,和该token的signature比较,如果一样,表示是正常的token,就可以继续往后访问

5 base64介绍和使用

1 任何语言都有base64的加码和解码,转码方式(加密方式)
2 python中base64的加密与解密

    import base64

    import json
    dic_info={
      "name": "lqz",
      "age": 18
    }
    # 转成json格式字符串

    dic_str=json.dumps(dic_info)
    print(dic_str)
    #eyJuYW1lIjogImxxeiIsICJhZ2UiOiAxOH0=
    #eyJuYW1lIjogImxxeiIsICJhZ2UiOiAxOH0=
    # 需要用bytes格式
    # 加密
    base64_str=base64.b64encode(dic_str.encode('utf-8'))
    print(base64_str)


    # 解密

    res_bytes=base64.b64decode('eyJuYW1lIjogImxxeiIsICJhZ2UiOiAxOH0=')
    print(res_bytes)

6 jwt基本使用(jwt内置,控制用户登录后能访问和未登陆能访问)

1 drf中使用jwt,借助第三方https://github.com/jpadilla/django-rest-framework-jwt
2 pip3 install djangorestframework-jwt
3 快速使用(默认使用auth的user表)
	1 再默认auth的user表中创建一个用户
    2 在路由中配置
    	path('login/', obtain_jwt_token),
    3 用postman向这个地址发送post请求,携带用户名,密码,登陆成功就会返回token
    
    4 obtain_jwt_token本质也是一个视图类,继承了APIView
    	-通过前端传入的用户名密码,校验用户,如果校验通过,生成token,返回
        -如果校验失败,返回错误信息
    
4 用户登录以后才能访问某个接口
	-jwt模块内置了认证类,拿过来局部配置就可以
    -class OrderView(APIView):
        # 只配它不行,不管是否登录,都能范围,需要搭配一个内置权限类
        authentication_classes = [JSONWebTokenAuthentication, ]
        permission_classes = [IsAuthenticated,]
        def get(self, request):
            print(request.user.username)
            return Response('订单的数据')

5 用户未登录,不能访问
    -class OrderView(APIView):
        # 只配它不行,不管是否登录,都能范围,需要搭配一个内置权限类
        authentication_classes = [JSONWebTokenAuthentication, ]
        def get(self, request):
            print(request.user.username)
            return Response('订单的数据')
        
6 如果用户携带了token,并且配置了JSONWebTokenAuthentication,从request.user就能拿到当前登录用户,如果没有携带,当前登录用户就是匿名用户

7 前端要发送请求,携带jwt,格式必须如下
	-把token放到请求头中,key为:Authorization 
    -value必须为:jwt eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyX2lkIjo1LCJ1c2VybmFtZSI6ImVnb24xIiwiZXhwIjoxNjA1MjQxMDQzLCJlbWFpbCI6IiJ9.7Y3PQM0imuSBc8CUe_h-Oj-2stdyzXb_U-TEw-F82WE


7 控制登录接口返回的数据格式

1 控制登录接口返回的数据格式如下
    {
    code:100
    msg:登录成功
    token:asdfasfd
    username:egon
    }
    
2 写一个函数
	from homework.serializer import UserReadOnlyModelSerializer
    def jwt_response_payload_handler(token, user=None, request=None):
        return {'code': 100, 
                'msg': '登录成功',
                'token': token,
                'user': UserReadOnlyModelSerializer(instance=user).data
                }
3 在setting.py中配置
	import datetime
    JWT_AUTH = {
        'JWT_RESPONSE_PAYLOAD_HANDLER': 'homework.utils.jwt_response_payload_handler',
    }

8 自定义基于jwt的认证类

1 自己实现基于jwt的认证类,通过认证,才能继续访问,通不过认证就返回错误
2 代码如下
	
    class JwtAuthentication(BaseJSONWebTokenAuthentication):
        def authenticate(self, request):
            # 认证逻辑()
            # token信息可以放在请求头中,请求地址中
            # key值可以随意叫
            # token=request.GET.get('token')
            token=request.META.get('HTTP_Authorization'.upper())
            # 校验token是否合法
            try:
                payload = jwt_decode_handler(token)
            except jwt.ExpiredSignature:
                raise AuthenticationFailed('过期了')
            except jwt.DecodeError:
                raise AuthenticationFailed('解码错误')
            except jwt.InvalidTokenError:
                raise AuthenticationFailed('不合法的token')
            user=self.authenticate_credentials(payload)
            return (user, token)
 3 在视图类中配置
	authentication_classes = [JwtAuthentication, ]

作业

1 什么是集群,什么是分布式
2 什么是反向代理,什么是正向代理
3 (拓展)自己实现jwt的认证
	-{}.{}.asfasdf   前两部分用base64加密,最后一部分用md5+密码----》token 串
    -携带串过来 ,取出前俩部分,再用统一的md5+密码得到signature,跟携带过来的比较,通过(drf的认证类中)
4 研究什么是对称加密,什么是非对称加密
5 多方式登录(手机号登录,邮箱,用户名)+密码登录的接口,返回token

    
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值