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. hdu 1159 Common Subsequence 【LCS 基础入门】

    链接: http://acm.hdu.edu.cn/showproblem.php?pid=1159 http://acm.hust.edu.cn/vjudge/contest/view.action ...

  2. app返回之前app焦点的操作方法

    var hdWin,hdfocus: THandle; trdID: Cardinal; //获取前置app窗口句柄 hdWin := GetForegroundWindow;//FindWindow ...

  3. 蛇形命名法(snake case)驼峰命名法(camel case)字符转换问题

    描述小 Hi 写程序时习惯用蛇形命名法(snake case)为变量起名字,即用下划线将单词连接起来,例如:file_name. line_number.小 Ho 写程序时习惯用驼峰命名法(camel ...

  4. 前端基础之jQuery(Day55)

    阅读目录 一 jQuery是什么? 二 什么是jQuery对象? 三 寻找元素(选择器和筛选器) 四 操作元素(属性,css,文档处理) 扩展方法 (插件机制) 一. jQuery是什么? [1]   ...

  5. go——变量

    在数学概念中,变量(variable)表示没有固定值且可以改变的数.但从计算机系统实现角度来看,变量是一段或多段用来存储数据的内存.作为静态类型语言,Go语言总是有固定的数据类型,类型决定了变量内存的 ...

  6. Linux常用命令(更新)

  7. LightOJ - 1138 (二分+阶乘分解)

    题意:求阶乘尾部有Q(1 ≤ Q ≤ 108)个0的最小N 分析:如果给出N,然后求N!尾部0的个数的话,直接对N除5分解即可(因为尾部0肯定是由5*2构成,那么而在阶乘种,2的因子个数要比5少,所以 ...

  8. python入门三:文件操作

    一.文件操作 1.文件对象:和c一样,要想对一个文件进行操作,需要获取该文件的对象 f = open("xxx") # 打开文件并获取文件对象 f.xxx # 对文件进行某些操作 ...

  9. .NET计时器的使用-Stopwatch类

    作用: 微软提供的常用于统计时间消耗的类,作为一个固定的API接口供大家使用. 先看代码: using System; using System.Collections.Generic; using ...

  10. 面试:做过sql优化吗?

    近来面试找工作经常会遇见这种问题: 做过数据库优化吗?大数据量基础过吗?系统反应慢怎么查询? 这咱也没背过啊,面试还老问,现在的网站主要的压力都来自于数据库,频繁的数据库访问经常会使系统瘫痪,这样就需 ...