zoukankan      html  css  js  c++  java
  • python实现JWT

    python实现JWT

    一、常见的几种实现认证的方法

    1.1basic auth

    1.2cookie

    1.3token

    json web token--一种基于token的json格式web认证方法。基本原理是,第一次认证通过用户名和面膜,服务端签发一个json格式的token,后续客户端的请求都带着这个token,服务端仅需要解析这个token,来判断客户端的身份和合法性。jwt协议只是规范了这个协议的格式,分为三个部分

    1.3.1header头部

    {
        'type':'JWT',   #声名类型,这里是JWT
        'alg':'HS256'  #声名加密的算法,通常为 HMAC  SHA256
    }
    

    再将其解析base64编码

    1.3.2payload载荷

    payload是放置实际有效信息的地方。jwt定义了几种内容,包括:
    
      标准中注册的声明,如签发者,接收者,有效时间(exp),时间戳(iat,issued at)等;为官方建议但非必须
      公共声明
      私有声明
    

      

    #一个常见的payload
    {
        'user_id':12345,
        'user_role':admin,
        'iat':14234234
    }
    

     

    // 包括需要传递的用户信息;
    { "iss": "Online JWT Builder",       #该JWT的签发者,是否使用是可选的;
      "iat": 1416797419,                #在什么时候签发的(UNIX时间),是否使用是可选的;
      "exp": 1448333419,                #什么时候过期,这里是一个Unix时间戳,是否使用是可选的;
      "aud": "www.gusibi.com",           #接收该JWT的一方,是否使用是可选的;
      "sub": "uid",                        #该JWT所面向的用户,是否使用是可选的;
      "nickname": "goodspeed", 
      "username": "goodspeed", 
      "scopes": [ "admin", "user" ] 
    }            
    

      

     

    1.3.3signature

      原理

    // 根据alg算法与私有秘钥进行加密得到的签名字串;
    // 这一段是最重要的敏感信息,只能在服务端解密;
    HMACSHA256(  
        base64UrlEncode(header) + "." +
        base64UrlEncode(payload),
        SECREATE_KEY
    )
    第三部分是个签证信息,有三部分组成:
    header(base64后的)
    payload(base64后的)
    secret

    存储了序列化的secreate key和salt key。这个部分需要base64加密后的header和base64加密后的payload使用.连接组成的字符串,
    然后通过header中声明的加密方式进行加盐secret组合加密,然后就构成了jwt的第三部分。

     示例图:

    二、认证需求

    目标场景是一个前后端分离的后端系统,用于运维工作,虽在内网使用,也有一定的保密性要求
        API为restful+json的无状态接口,要求认证也是相同模式
        可横向扩展
        较低数据库压力
        证书可注销
        证书可自动延期
    这样就选择JWT

    三、JWT实现

    如何生成token

    import jwt
    import time
    
    # 使用 sanic 作为restful api 框架 
    def create_token(request):
        grant_type = request.json.get('grant_type')
        username = request.json['username']
        password = request.json['password']
        if grant_type == 'password':
            account = verify_password(username, password)
        elif grant_type == 'wxapp':
            account = verify_wxapp(username, password)
        if not account:
            return {}
        payload = {
            "iss": "gusibi.com",
             "iat": int(time.time()),
             "exp": int(time.time()) + 86400 * 7,
             "aud": "www.gusibi.com",
             "sub": account['_id'],
             "username": account['username'],
             "scopes": ['open']
        }
        token = jwt.encode(payload, 'secret', algorithm='HS256')
        return True, {'access_token': token, 'account_id': account['_id']}
        
    
    def verify_bearer_token(token):
        #  如果在生成token的时候使用了aud参数,那么校验的时候也需要添加此参数
        payload = jwt.decode(token, 'secret', audience='www.gusibi.com', algorithms=['HS256'])
        if payload:
            return True, token
        return False, token
    View Code

    如何解析token

    四、优化

    总结

    我们做了一个JWT的认证模块:
    (access token在以下代码中为'token',refresh token在代码中为'rftoken')
    
    首次认证
    client -----用户名密码-----------> server
    
    client <------token、rftoken----- server
    
    access token存续期内的请求
    client ------请求(携带token)----> server
    
    client <-----结果----------------- server
    
    access token超时
    client ------请求(携带token)----> server
    
    client <-----msg:token expired--- server
    
    重新申请access token
    client -请求新token(携带rftoken)-> server
    
    client <-----新token-------------- server
    
    rftoken token超时
    client -请求新token(携带rftoken)-> server
    
    client <----msg:rftoken expired--- server
    
    如果设计一个针对此认证的前端,需要:
    
    存储access token、refresh token
    
    访问时携带access token,自动检查access token超时,超时则使用refresh token更新access token;状态延期用户无感知
    
    用户登出直接抛弃access token与refresh token
    

      

  • 相关阅读:
    编码问题:python写入文件
    [ExtJS5学习笔记]第三十二节 sencha extjs 5与struts2的ajax交互配置
    PS 滤镜——Skewing
    [struts2学习笔记] 第六节 struts2依赖的jar包还有Could not find action or result 错误解决
    [linux RedHat]windows下使用putty远程连接linux 下载JDK和tomcat
    一个有趣的花环图案生成函数
    【翻译】针对多种设备定制Ext JS 5应用程序
    【翻译】Ext JS最新技巧——2015-1-2
    [ExtJS5学习笔记]第三十一节 sencha extjs 5使用cmd生成的工程部署到tomcat服务器
    PhotoShop 图像处理 算法 汇总
  • 原文地址:https://www.cnblogs.com/djfboai/p/10670714.html
Copyright © 2011-2022 走看看