zoukankan      html  css  js  c++  java
  • django-restframework-jwt认证基础使用等相关内容-89

    1 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,就可以继续往后访问

     

    2 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)

     

    3 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

     

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

    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',
      }

     

    5 自定义基于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, ]

     

  • 相关阅读:
    treesurgeon
    WatiN
    综艺《燃烧吧!天才程序员》:科技类真人秀凭什么吸引人?它是在消费群体吗?
    海外IT老兵谈996:人才不是加班加出来的,期待有企业能站出来破局
    C语言游戏脚本:利用API 函数实现一个简单的超级玛丽外挂!
    C语言基础丨运算符之逻辑运算符(四)
    40岁程序员被90后训斥不996,这世界怎么了?
    C语言丨关键字signed和unsigned 的使用与区别详解
    C语言基础丨运算符之关系运算符(三)
    最硬核的方式找女朋友:用 VS Code 找对象?还是不看脸的那种?!
  • 原文地址:https://www.cnblogs.com/usherwang/p/14304504.html
Copyright © 2011-2022 走看看