• jwt 认证


    jwt 认证示意图

    jwt 优势

    1 没有数据库写操作,高效

    2 服务器不存 token,低耗

    3 签发检验都是算法,集群



    jwt 认证算法:签发与检验

    1. jwt 三段式:头 . 体 . 签名 (head.payload.sgin)

    2. 头和体是可逆加密,让服务器可以反解除 user 对象,签名是不可逆加密,保证整个token的安全性的

    3. 头体签名三部分,都是采用 json 格式的字符串,进行加密,可逆加密一般采用 base64 算法,不可逆加密一般采用 hash(md5) 算法

    4. 头中的内容是基本信息:公司信息,项目组信息,token 采用的加密方式信息

      {
      	"company": "公司信息",
      	...
      }
      
    5. 体中的内容是关键信息:用户主键,用户名,签发是客户端信息(设备号,地址),过期时间

      {
      	"user_id": 1,
      	...
      }
      
    6. 签名中的内容是安全信息:头的加密结果 + 体的加密结果 + 服务器不对外公开的安全吗 进行 md5 加密

      {
      	"head": "头的加密字符串",
      	"payload": "体的加密字符串",
      	"secret_key": "安全码"
      }
      

    签发

    根据登陆请求提交来的 账号 + 密码 + 设备信息 签发 token

    1. 用基本信息存储 json 字典,采用 base64 算法加密得到 头字符串
    2. 用关键信息存储 json 字典,采用 base64 算法加密得到 体字符串
    3. 用头、体加密字符串再加安全码信息存储 json 字典,采用 hash md5 算法加密得到 签名字符串

    校验

    根据客户端带 token 的请求,反解除 user 对象

    1. 将 token按“ . ”拆分为三段字符串,第一段头加密字符串,一般不需要做任何处理
    2. 第二段体加密字符串,要反解出用户主键,通过主键从 User 表中就能得到登陆用户,过期时间和设备信息都是安全信息,确保 token 没过期,且是同一设备来的
    3. 再用 第一段 + 第二段 + 服务器安全吗 不可逆 md5 加密,与第三段字符串进行碰撞校验,通过后才能代表第二段校验得到的 user 对象就是合法的登陆用户

    drf 项目的 jwt 认证开发流程(重点)

    1. 用账号密码访问登陆接口,登陆接口逻辑中调用 签发 token 算法,得到 token,返回给客户端,客户端自己存到 cookies 中
    2. 校验 token 的算法应该写在认证类中(在认证类中调用),全局配置给认证组件,所有视图类请求,都会校验,所以请求带来了 token,就会反解出 user 对象,在视图类中用 request.user 就能访问登陆的用户

    注意:登陆接口需要做 认证 + 权限 两个局部禁用



    drf-jwt 框架基本使用

    安装

    pip install djangorestframework-jwt
    

    签发 token(登陆接口):视图类已经写好了,配置一下路由就行(urls.py)

    # api/urls.py
    from rest_framework_jwt.views import ObtainJSONWebToken
    urlpatterns = [
        # ...
        url('^login/$', ObtainJSONWebToken.as_view()),
    ]
    
    # Postman请求:/api/login/,提供username和password即可
    

    校验 token (认证组件):认证类已经写好了,全局配置一下组件就行了(settings.py)

    # drf-jwt的配置
    import datetime
    JWT_AUTH = {
        # 配置过期时间
        'JWT_EXPIRATION_DELTA': datetime.timedelta(days=7),
    }
    
    
    # drf配置(把配置放在最下方)
    REST_FRAMEWORK = {
        # 自定义三大认证配置类们
        'DEFAULT_AUTHENTICATION_CLASSES': ['rest_framework_jwt.authentication.JSONWebTokenAuthentication'],
        # 'DEFAULT_PERMISSION_CLASSES': [],
        # 'DEFAULT_THROTTLE_CLASSES': [],
    }
    

    设置需要登陆才能访问的接口进行测试(views.py)

    from rest_framework.permissions import IsAuthenticated
    class UserCenterViewSet(GenericViewSet, mixins.RetrieveModelMixin):
        # 设置必须登录才能访问的权限类
        permission_classes = [IsAuthenticated, ]
    
        queryset = models.User.objects.filter(is_active=True).all()
        serializer_class = serializers.UserCenterSerializer
    

    测试访问登陆认证接口(Postman)

    """
    1)用 {"username": "你的用户", "password": "你的密码"} 访问 /api/login/ 接口等到 token 字符串
    
    2)在请求头用 Authorization 携带 "jwt 登录得到的token" 访问 /api/user/center/1/ 接口访问个人中心
    """
    


    token 刷新机制(了解)

    drf-jwt 直接提供刷新功能

    """
    1)运用在像12306这样极少数安全性要求高的网站
    2)第一个token由登录签发
    3)之后的所有正常逻辑,都需要发送两次请求,第一次是刷新token的请求,第二次是正常逻辑的请求
    """
    

    settings.py

    import datetime
    
    JWT_AUTH = {
        # 配置过期时间
        'JWT_EXPIRATION_DELTA': datetime.timedelta(minutes=5),
    
        # 是否可刷新
        'JWT_ALLOW_REFRESH': True,
        # 刷新过期时间
        'JWT_REFRESH_EXPIRATION_DELTA': datetime.timedelta(days=7),
    }
    

    urls.py

    from rest_framework_jwt.views import ObtainJSONWebToken, RefreshJSONWebToken
    urlpatterns = [
        url('^login/$', ObtainJSONWebToken.as_view()),  # 登录签发token接口
        url('^refresh/$', RefreshJSONWebToken.as_view()),  # 刷新toekn接口
    ]
    

    postman

    # 接口:/api/refresh/
    # 方法:post
    # 数据:{"token": "登录签发的token"}
    
  • 相关阅读:
    oracle
    mysql的必知技巧
    sql_update
    sql查询
    Java 动态页面技术 之 jsp
    Java 会话技术 之 session
    Java 会话技术 之cookie
    Java HttpServletRequest
    Java HttpServletResponse
    Java Servlet接口、web.xml配置、HttpServlet父类
  • 原文地址:https://www.cnblogs.com/kai-/p/12363229.html
Copyright © 2020-2023  润新知