内容简介:简单解释即:JWT是一个紧凑的、URL安全的、用于在双方之间传输claims的这样一个方法。而这个claims是用JSON格式编码的,并且进行了数字签名。claim - 声明;宣称;断言;(尤指对财产、土地等要求拥有的)所有权;(尤指向公司、政府等)索款,索赔。让我们看一看具体的JWT长什么样子,就知道这个单词用的其实是相当贴切的。
JSON Web Token (JWT) is a compact URL-safe means of representing claims to be transferred between two parties. The claims in a JWT are encoded as a JSON object that is digitally signed using JSON Web Signature (JWS).
简单解释即:JWT是一个紧凑的、URL安全的、用于在双方之间传输claims的这样一个方法。而这个claims是用JSON格式编码的,并且进行了数字签名。
claim - 声明;宣称;断言;(尤指对财产、土地等要求拥有的)所有权;(尤指向公司、政府等)索款,索赔。让我们看一看具体的JWT长什么样子,就知道这个单词用的其实是相当贴切的。
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJpZDEyMyIsIm5hbWUiOiJKb2huIERvZSIsImlhdCI6MTUxNjIzOTAyMiwiZXhwIjoxNTE2MjM5MDk5fQ.8HLeWIBn5d87r-XItgQJOnwqYGjJYrpKmz-2eC9fb8A
这个就是一个JWT的串,它分为3个部分,分别由两个 .
隔开,这三个部分分别是:
Header
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9 // 是下面这个JSON object的base64编码,它是JWT的头信息 // 表明了这个JWT用的是哪种签名算法,以及类型(JWT) { "alg": "HS256", "typ": "JWT" } 复制代码
Payload
eyJpc3MiOiJpZDEyMyIsIm5hbWUiOiJKb2huIERvZSIsImlhdCI6MTUxNjIzOTAyMiwiZXhwIjoxNTE2MjM5MDk5fQ // 是羡慕这个JSON object的base64编码 { "iss": "id123", "name": "John Doe", "iat": 1516239022, "exp": 1516239099 } 复制代码
Payload里放的其实就是claims(声明),在使用中。JWT一般都是由服务器返回给客户端的,而客户端每次请求时都会带上这个JWT串,服务端通过解析这个Payload里的内容,就知道这个请求来自于哪个用户以及一些其他用户基本信息。
上面的这四个字段 iss
, name
, iat
, exp
,除了 name
都是RFC7519定义的一些 Registered Claim Names, 可以认为标准的claim名字。 iss
表示这个token是由谁签发的, iat
token签发的时间, exp
token过期时间。我们也可以像 name
一样,加一些自身逻辑需要的字段。
那么为什么说claim这个单词用的很贴切呢?首先,payload里往往会是一些和身份认证、资源访问权限相关的内容;其次,payload字段经过base64解码之后,完全都是明文,任何人都可以修改,甚至伪造。也就是说任何人都可以通过伪造payload的内容来声称自己是谁、或者具有何种权限,这都只是单方面的声明,并不一定是有效/合法的。而要想知道是否合法,则需要第三个部分:
Signature
8HLeWIBn5d87r-XItgQJOnwqYGjJYrpKmz-2eC9fb8A // 计算HMAC SHA-256签名值, 之后进行base64编码 base64urlsafeencode( (HMACSHA256( base64UrlEncode(header) + "." + base64UrlEncode(payload), secret ) ) 复制代码
有了签名,只需要对收到的JWT再进行一次签名校验就能知道这个JWT是不是合法的了。HS256(HMACSHA256)是jwt支持的签名算法之一,其他的详见RFC7519
JSON in Flutter
接上文的Payload:
{ "iss": "id123", "name": "John Doe", "iat": 1516239022, "exp": 1516239099 } 复制代码
要解析这条数据,我们需要dart:convert为提供的 jsonDecode
函数:
import 'dart:convert'; Map<String, dynamic> payload = jsonDecode(jsonString); print('${payload["iss"]} and ${payload["name"]}'); 复制代码
jsonDecode
函数签名返回值是一个 dynamic
类型, dynamic
可以是任意类型,字符串,数字,列表等。很明显, jsonDecode
需要能解析所有的合法 JSON
类型,它的返回值可以是多种不同的类型。而在我们的例子里, payload
是一个 Map<String, dynamic>
,因为我们知道 jsonString
是一个 JSON
的对象类型。
json编码也是同样简单:
var data = jsonEncode(payload); // data == '{"iss":"id123","name":"John Doe","iat":1516239022,"exp":1516239099}' 复制代码
除了以上手动方法之外,我们还可以用json_serializable来自动生成这些解析代码。
自动生成解析
首先你的pubspec.yaml需要一些额外的库
dependencies: json_annotation: ^2.0.0 dev_dependencies: build_runner: ^1.0.0 json_serializable: ^2.0.0 复制代码
定义Claim数据类(claim.dart)
import 'package:json_annotation/json_annotation.dart'; // 文件内容将会由 工具 自动生成 part 'claim.g.dart'; @JsonSerializable() class Claim { Claim(this.iss, this.name, this.iat, this.exp); String iss; String name; int iat; int exp; // 从json创建类对象的工厂函数,_$ClaimFromJson将会被定义在 claim.g.dart 文件中 factory Claim.fromJson(Map<String, dynamic> json) => _$ClaimFromJson(json); // 将对象转成json,_$ClaimToJson将会被定义在 claim.g.dart中 Map<String, dynamic> toJson() => _$ClaimToJson(this); } 复制代码
代码生成
运行 flutter packages pub run build_runner build
。 Done,你现在可以像这样使用Claim与json之间的转换了:
// decode Map map = jsonDecode(jsonString); var claim = Claim.fromJson(map); // encode String json = jsonEncode(claim); 复制代码
生成JWT串
import 'dart:convert'; import 'package:crypto/crypto.dart'; var header = jsonEncode(<String, dynamic>{ "alg": "HS256", "typ": "JWT" }); Claim claim = Claim("id123", "John Doe",1516239022,1516239099); String payload = jsonEncode(claim); var headerBase64 = base64Url.encode(utf8.encode(header)); var claimBase64 = base64Url.encode(utf8.encode(payload)); var key = utf8.encode('secret'); var bytes = utf8.encode(headerBase64 + "." + claimBase64); var hmacSha256 = new Hmac(sha256, key); // HMAC-SHA256 var digest = hmacSha256.convert(bytes); var signature = base64Url.encode(digest.bytes); print("Just get a fresh new jwt: $headerBase64.$claimBase64.$signature"); 复制代码
我们把这写功能稍微封装一下,就是一个简单的jwt编码函数,可以处理任何 @JsonSerializable()
注解的类实例。
String encodeJWT(dynamic obj) { var header = jsonEncode(<String, dynamic>{"alg": "HS256", "typ": "JWT"}); String payload = jsonEncode(obj); var headerBase64 = base64Url.encode(utf8.encode(header)); var claimBase64 = base64Url.encode(utf8.encode(payload)); var key = utf8.encode('secret'); var bytes = utf8.encode(headerBase64 + "." + claimBase64); var hmacSha256 = new Hmac(sha256, key); // HMAC-SHA256 var digest = hmacSha256.convert(bytes); var signature = base64Url.encode(digest.bytes); return "$headerBase64.$claimBase64.$signature"; } 复制代码
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网
猜你喜欢:- 安卓 so 文件解析详解
- Dubbo标签解析详解 原 荐
- 【Spring】BeanFactory 解析 bean 详解
- 成本计算引擎动态规则解析技术详解
- Reface.NPI 方法名称解析规则详解
- 详解js的作用域、预解析机制
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
电子商务:管理与社交网络视角(原书第7版)
(美)埃弗雷姆·特班(Efraim Turban)、戴维.金(David King)、李在奎、梁定澎、德博拉·特班(Deborrah Turban) / 时启亮、陈育君、占丽 / 机械工业出版社 / 2014-1-1 / 79.00元
本书对电子学习、电子政务、基于web的供应链、协同商务等专题进行了详细的介绍,全书涵盖丰富的资料以及个案,讨论了Web 2.0环境内的产业结构、竞争变化以及对当今社会的影响。另外,本书在消费者行为、协同商务、网络安全、网络交易及客户管理管理、电子商务策略等内容上都有最新的改编,提供读者最新颖的内容,贴近当代电子商务的现实。 本书适合高等院校电子商务及相关专业的本科生、研究生及MBA学员,也可......一起来看看 《电子商务:管理与社交网络视角(原书第7版)》 这本书的介绍吧!