zoukankan      html  css  js  c++  java
  • JSON Web Tokens 系统用户认证 jwt

    一种开发的行业标准 RFC 7519 ,用于安全的表示双方之间的声明。
    广泛应用在系统的用户认证

    浏览器发送 用户名和密码 到服务器中,服务端判断用户名和密码是否正确,
    如果正确则生成一个 token,并返回给浏览器

    浏览器每次都要带有服务端返回的 token ,一起进行请求,
    由服务端校验 token 的合法性
    如果合法则返回数据,不合法则返回浏览器错误信息

    jwt 生成 token 的示例如下(总共为三段字符串,使用 . 进行分隔)
    eyJ0eXAiOiJqd3QiLCJhbGciOiJIUzI1NiJ9.
    eyJ1c2VyX2lkIjoxMTExLCJ1c2VybmFtZSI6IkhhbnkiLCJleHAiOjE2MDI3MjQxMTZ9.
    -ivPhXGKYAn7ON0rMInChUBHMjiBOtvthHhdwcxvkRY

    第一段字符串表示为
    eyJ0eXAiOiJqd3QiLCJhbGciOiJIUzI1NiJ9.
    是 HEADER 部分,固定包含算法和 token 类型,
    对 json 进行 base64url 加密
    
        headers = {
            'typ': 'jwt',
            'alg': 'HS256'
        }

    第二段字符串表示为
    eyJ1c2VyX2lkIjoxMTExLCJ1c2VybmFtZSI6IkhhbnkiLCJleHAiOjE2MDI3MjQxMTZ9.
    是 payload 部分,包含有一部分数据,对 json 进行 base64url 加密
    
        payload = {
            'user_id': 1111, # 自定义用户ID
            'username': 'Hany', # 自定义用户名
            'exp': datetime.datetime.utcnow() + datetime.timedelta(minutes=5) # 超时时间
        }

    第三段字符串表示为
    -ivPhXGKYAn7ON0rMInChUBHMjiBOtvthHhdwcxvkRY
    将前两段字符串的密文通过 . 进行拼接起来,然后使用 HS256 进行加密,
    对 HS256 密文进行 base64url 加密,得到 token 的第三段
    
        base64url(
            HMACSHA256(
              base64UrlEncode(header) + "." + base64UrlEncode(payload),
              your-256-bit-secret (秘钥加盐)
            )
        )

    替换规则:
    base64url 加密是先做 base64 加密,然后再将 - 替代 + , _ 替代 /

    关于 jwt 的安装
    pip install jwt

    基于 Python 的 pyjwt 实现代码:
    
    import jwt
    import datetime
    SALT = 'iv%x6xo7l7_u9bf_u!9#g#m*)*=ej@bek5)(@u3kh*72+unjv='
    
    def create_token():
        # 构造header
        headers = {
            'typ': 'jwt',
            'alg': 'HS256'
        }
        # 构造payload
        payload = {
            'user_id': 1111, # 自定义用户ID
            'username': 'Hany', # 自定义用户名
            'exp': datetime.datetime.utcnow() + datetime.timedelta(minutes=5) # 超时时间
        }
        result = jwt.encode(payload = payload, key = SALT, algorithm = "HS256", headers = headers).decode('utf-8')
        return result
    
    if __name__ == '__main__':
        token = create_token()
        print(token)

    浏览器 会携带服务器端返回的 token 进行 超时 及 合法性 校验
    服务器端在获取到用户携带的 token 后,会对 token 解密为三个字符串
    即 header_segment , payload_segment , crypto_segment 三部分
    然后对 header_segment , payload_segment , crypto_segment 进行 base64url 解密,
    得到 header , payload , signature 三部分
    服务器端会对 signature 这一部分进行合法性校验
    
    校验规则如下:
        jwt 生成 token 的前两段字符(第二个 . 之前的所有字符),
            即 对 HEADER 和 payload 进行 base64url 加密后产生的字符串
        (从第一段明文中)获取加密算法,默认 HS256
        使用 算法 + 盐 对 token 的前两段字符进行加密,将得到的结果与第三段 signature 密文进行比较

    实现代码:
    
    import jwt
    from jwt import exceptions
    def get_payload(token):
        try:
            SALT = 'iv%x6xo7l7_u9bf_u!9#g#m*)*=ej@bek5)(@u3kh*72+unjv='
            verified_payload = jwt.decode(token, SALT, True)
            print("token 认证成功")
            return verified_payload
        except exceptions.ExpiredSignatureError:
            print('token 已失效')
        except jwt.DecodeError:
            print('token 认证失败')
        except jwt.InvalidTokenError:
            print('非法的 token')
            
    if __name__ == '__main__':
        token = "eyJ0eXAiOiJqd3QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyX2lkIjoxMTExLCJ1c2VybmFtZSI6IkhhbnkiLCJleHAiOjE2MDI3MjY1MjN9.r49ST_8v71BswEkvOSGjyGWY5J6ksmz8BCAhZNxjgOg"
        payload = get_payload(token)
    
    
    注: token 可以先自己手动生成一份,然后再进行复制粘贴到此代码中,进行 jwt 的用户认证

    参考链接:
    
    https://www.pythonav.com/wiki/detail/6/67/

    2020-10-15

  • 相关阅读:
    700.二叉搜索树中的搜索
    645.错误的集合
    567.字符串的排列
    560.和为K的子数组
    518.零钱兑换 II
    516.最长回文子序列
    509.斐波那契数
    503.下一个更大元素 II
    496.下一个更大元素 I
    leetcode 1171 Remove Zero Sum Consecutive Nodes from Linked List
  • 原文地址:https://www.cnblogs.com/hany-postq473111315/p/13818871.html
Copyright © 2011-2022 走看看