JSON Web Token (JWT) 是一种基于 token 的认证方案。

JSON Web Token 的结构

一个 JWT token 看起来是这样的:

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjEzODY4OTkxMzEsImlzcyI6ImppcmE6MTU0ODk1OTUiLCJxc2giOiI4MDYzZmY0Y2ExZTQxZGY3YmM5MGM4YWI2ZDBmNjIwN2Q0OTFjZjZkYWQ3YzY2ZWE3OTdiNDYxNGI3MTkyMmU5IiwiaWF0IjoxMzg2ODk4OTUxfQ.uKqU9dTB6gKwG6jQCuXYAiMNdfNRw98Hw_IWuA5MaMo

可以简化为下面这样的结构:

base64url_encode(Header) + '.' + base64url_encode(Claims) + '.' + base64url_encode(Signature)

Header

Header 包含了一些元数据,至少会表明 token 类型以及 签名方法。比如

{
"typ" : "JWT",
"alg" : "HS256"
}
  • type: 必需。token 类型,JWT 表示是 JSON Web Token.
  • alg: 必需。token 所使用的签名算法,可用的值在 这里 有规定。

Claims (Payload)

Claims 部分包含了一些跟这个 token 有关的重要信息。 JWT 标准规定了一些字段,下面节选一些字段:

  • iss: The issuer of the token,token 是给谁的
  • sub: The subject of the token,token 主题
  • exp: Expiration Time。 token 过期时间,Unix 时间戳格式
  • iat: Issued At。 token 创建时间, Unix 时间戳格式
  • jti: JWT ID。针对当前 token 的唯一标识

除了规定的字段外,可以包含其他任何 JSON 兼容的字段。

Payload 示例:

{
"iss": "mozillazg.com",
"exp": 1435055117,
"user_id": 1,
"foo": "bar"
}

Signature

JWT 标准遵照 JSON Web Signature (JWS) 标准来生成签名。签名主要用于验证 token 是否有效,是否被篡改。 签名时可以 这些算法进行签名,比如 HMAC SHA-256:

content = base64url_encode(Header) + '.' + base64url_encode(Claims)
signature = hmacsha256.hash(content)

说到这里有一点需要特别注意的是,默认情况下,JWT 中信息都是明文的,即 Claims 的内容并没有 被加密,可以通过 base64url_decode(text) 的方式解码得到 Claims 。 所以,不要在 Claims 里包含敏感信息,如果一定要包含敏感信息的话,记得先将 Claims 的内容进行加密(比如,使用 JSON Web Encryption (JWE) 标准进行加密) 然后在进行 base64url_encode 操作。

Python 实现

已有的轮子: 上 PyPI 上 搜索 JWT 即可。 用的比较多是 PyJWT 。

手动简单实现

import base64
import json
import hashlib
import hmac def base64url_encode(s):
return base64.urlsafe_b64encode(s).replace('=', '') headers = json.dumps({
"typ" : "JWT",
"alg" : "HS256"
})
claims = json.dumps({
"iss": "mozillazg.com",
"exp": 1435055117,
"user_id": 1,
"foo": "bar"
})
content = base64url_encode(headers) + '.' + base64url_encode(claims)
secret_key = 'your secret key'
signature = hmac.new(secret_key, content, hashlib.sha256).digest() token = content + '.' + base64url_encode(signature)

最后得到的 token 的值是

eyJhbGciOiAiSFMyNTYiLCAidHlwIjogIkpXVCJ9.eyJpc3MiOiAibW96aWxsYXpnLmNvbSIsICJmb28iOiAiYmFyIiwgInVzZXJfaWQiOiAxLCAiZXhwIjogMTQzNTA1NTExN30.iFAK1B-6xRlmlSHnS2P24wsS6Ko6iZjbSPHdldzIhp4

之所以用 base64url_encode 而不是 base64.b64encode 是因为 token 可能会被用作 url 参数, 而 base64 中的 +, /, =在 url 里被转义成 %2B %2F %3D,导致 token 的值变得更长了,所以这里使用 base64url 即进行如下替换 + -> -/ -> _, 删除=

再次提示, claims 的值并没有被加密,就算不知道 secert_key 的值也可以得到 claims 的值。

参考资料:

JSON Web Token (JWT) 简介的更多相关文章

  1. JSON WEB Token(JWT)

    最近面试被问及单点登陆怎么解决?自己的项目前后端分离,自己实现token认证,token有失效时间,token中包含用户基本的信息.且一个当用户重新登陆后,原来的token就会失效,这么安全的一个to ...

  2. JSON Web Token (JWT) 实现与使用方法

    1. JSON Web Token是什么 JSON Web Token (JWT)是一个开放标准(RFC 7519),它定义了一种紧凑的.自包含的方式,用于作为JSON对象在各方之间安全地传输信息.该 ...

  3. Json Web Token(JWT)详解

    什么是Json Web Token Json web token (JWT), 是为了在网络应用环境间传递声明而执行的一种基于JSON的开放标准((RFC 7519).该token被设计为紧凑且安全的 ...

  4. JSON Web Token (JWT),服务端信息传输安全解决方案。

    JWT介绍 JSON Web Token(JWT)是一种开放标准(RFC 7519),它定义了一种紧凑独立的基于JSON对象在各方之间安全地传输信息的方式.这些信息可以被验证和信任,因为它是数字签名的 ...

  5. 漫谈JSON Web Token(JWT)

    一.背景 传统的单体应用基于cookie-session的身份验证流程一般是这样的: 用户向服务器发送账户和密码. 服务器验证账号密码成功后,相关数据(用户角色.登录时间等)都保存到当前会话中. 服务 ...

  6. 基于 Token 的身份验证:JSON Web Token(JWT)

    1.传统身份验证和JWT的身份验证 传统身份验证:       HTTP 是一种没有状态的协议,也就是它并不知道是谁是访问应用.这里我们把用户看成是客户端,客户端使用用户名还有密码通过了身份验证,不过 ...

  7. JSON Web Token (JWT) - Introduction

    To validate the challenge, connect as admin.------------以admin登陆 https://jwt.io/introduction/        ...

  8. JWT(JSON Web Token)原理简介

    原文:http://www.fengchang.cc/post/114 参考了一下这篇文章:https://medium.com/vandium-software/5-easy-steps-to-un ...

  9. json web token JWT实现TP5创建和验证

    根据博客进行jwt初始化配置 https://blog.csdn.net/weixin_43389208/article/details/117442266?spm=1001.2014.3001.55 ...

随机推荐

  1. delphi xe----操作mongoDB驱动,TMongoWire(Delphi MongoDB Driver)

    所有例子来自:https://github.com/stijnsanders/TMongoWire Delphi MongoDB的驱动 一个Delphi的驱动程序来访问mongoDB的服务器.用jso ...

  2. 开机启动/etc/rc.local失效无效怎么办?解决方法

    开机启动/etc/rc.local失效问题的解决方法 第一种情况:当centOS 随机启动文件 /etc/rc.local 失效时请按如下修改1.echo /etc/rc.local >> ...

  3. 第13章—数据库连接池(Druid)

    spring boot 系列学习记录:http://www.cnblogs.com/jinxiaohang/p/8111057.html 码云源码地址:https://gitee.com/jinxia ...

  4. MySQL前后台交互登录系统设计

    1.首先我们做一个前台的注册页面 <!DOCTYPE html> <html> <head> <meta charset="UTF-8"& ...

  5. Piggy-Bank---hdu1114(完全背包)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1114 题意是有一个存钱罐,当它是空的时候重量为E,满的时候重量为F:已知存钱罐里面有 n 种钱,每种钱 ...

  6. MongoDB资料汇总(转)

    原文:MongoDB资料汇总 上一篇Redis资料汇总专题很受大家欢迎,这里将MongoDB的系列资料也进行了简单整理.希望能对大家有用. 最后更新时间:2013-04-22 1.MongoDB是什么 ...

  7. Pycharm选中代码无法Backspace直接删除

    现象 如图,选中代码后,按习惯来说,直接Backspace就可以删除被选中代码. 但选中后再按“Backspace”,只会改变(扩选)选中范围. 解决 点击“工具栏”里的“Tool”,去掉勾选的Vim ...

  8. Andrew Ng机器学习编程作业:Regularized Linear Regression and Bias/Variance

    作业文件: machine-learning-ex5 1. 正则化线性回归 在本次练习的前半部分,我们将会正则化的线性回归模型来利用水库中水位的变化预测流出大坝的水量,后半部分我们对调试的学习算法进行 ...

  9. 003-基于URL的权限管理[不使用shiro]

    一.基于url权限管理流程[实现步骤] 基于url拦截是企业中常用的权限管理方法,实现思路是:将系统操作的每个url配置在权限表中,将权限对应到角色,将角色分配给用户,用户访问系统功能通过Filter ...

  10. Docker 网络之端口绑定

    外部访问容器 容器中可以运行一些网络应用,要让外部也可以访问这些应用,可以通过 -P 或 -p 参数来指定端口映射. -P 标记时 Docker 会随机映射一个 49000~49900 的端口到内部容 ...