https://github.com/lcobucci/jwt/releases/tag/3.3.0
Implicit conversion of keys from strings is deprecated. Please use InMemory or LocalFileReference classes.
This release introduces a forward compatibility layer for the next major release (v4.0.0), guiding users to make their code compatible with both versions.
JSON Web Token 是什么
JSON Web Token (JWT)是开放标准(RFC 7519),定义了紧凑的、自包含的方式,用于作为JSON对象在各方安全传输信息。
信息被验证和信任,因为它是数字签名的
什么时候用JSON Web Token
Authorization (授权)
JWT最常见场景 用户登录 后续每个请求都包含JWT 允许用户访问该令牌允许的路由 服务 资源
单点登录是现在广泛使用JWT特性 开销小 跨域轻松
Information Exchange (信息交换)
安全在各方之间传输信息而言 JSON Web Tokens无疑是一种很好的方式
JWT可以被签名,用公钥/私钥对,确定发送人就是它们所说的那个人
签名使用头和有效负载计算的,验证内容没有被篡改
JSON Web Token结构
JSON Web Token由三部分组成,用圆点(.)连接
三部分分别是
HeaderPayloadSignature
典型的JWT看起来 xxxxx.yyyyy.zzzzz
Header header典型的由两部分组成
token的类型 JWT 和算法名称(比如:HMAC SHA256或者RSA等等)
如{ 'alg': "HS256",  'typ': "JWT"} 用Base64对这个JSON编码就得到JWT的第一部分
Payload JWT的第二部分是payload,包含声明(要求)声明是关于实体(通常是用户)和其他数据的声明
声明有三种类型
registered
public
private
Registered claims
预定义的声明,不强制的,但是推荐。

iss (issuer)
exp (expiration time)
sub (subject)
aud (audience)等
Public claims 随意定义
Private claims 同意使用它们的各方之间共享信息,不是注册的或公开的声明
{"sub": '123456789',"name": 'john', "admin":true}
对payload进行Base64编码得到JWT的第二部分
不要在JWT的payload或header中放置敏感信息,除非是加密的
Signature
为了签名部分,必须有编码过的header、编码过的payload、一个秘钥,签名算法 header 中指定的,然对它们签名即可
如  HMACSHA256(base64UrlEncode(header) + "." + base64UrlEncode(payload), secret )
签名是用于验证消息在传递过程中有没有被更改,并且,对于使用私钥签名的token,它还可以验证JWT的发送方是否为它所称的发送方。

JSON Web Tokens 如何工作
认证时,当用户用凭证成功登录以后,JSON Web Token被返回。
token 是用户凭证,小心以防止安全问题
保存令牌时不应该超过你所需要的时间
无论何时用户想要访问受保护的路由或者资源的时候,用户代理(通常是浏览器)都应该带上JWT,典型的,
通常放在Authorization header中用Bearer schema
header是这样的
Authorization: Bearer
服务器上的受保护的路由将会检查Authorization header中的JWT是否有效
有效则可以访问受保护的资源。
如JWT包含足够多的必需的数据,就可减少对某些操作的数据库查询的需要,尽管可能并不总是如此。
如果token是在授权头(Authorization header)中发送的,那么不会有跨源资源共享(CORS)问题,因为不用cookie
基于Token的身份认证 与 基于服务器的身份认证
基于服务器的身份认证
基于Token的身份认证工作及好处
HTTP协议无状态
已经认证用户,下一次请求时服务器必须再次认证
传统的做法是将已经认证过的用户信息存储在服务器上,如Session
下次请求时带Session ID 服务器以此检查用户是否认证过
基于服务器的身份认证问题
Sessions 每次用户认证通过以后,服务器需要创建一条记录保存用户信息,常在内存,用户多服务器开销大
Scalability 由于Session是在内存中的,这就带来一些扩展性的问题
CORS当要扩展应用,让数据被多个移动设备使用时,考虑跨资源共享问题
用AJAX调用从另一个域名下获取资源时 可能遇到禁止请求的问题
CSRF 用户很容易受到CSRF攻击

JWT与Session差异
相同点是,它们都是存储用户信息;然而,Session是在服务器端的,而JWT是在客户端的。
Session方式存储用户信息的最大问题在于要占用大量服务器内存,增加服务器的开销。
JWT方式将用户状态分散到客户端,减轻服务端的内存压力
Session状态存储在服务器端,客户端只有session id;
Token状态存储在客户端

基于Token的身份认证如何工作
Token身份认证无状态,服务器或Session不存储用户信息
没有会话信息 应用程序可根据需要扩展和添加更多的机器,不担心用户登录的位置
主要流程
用户携带用户名和密码请求访问 服务器校验用户凭据
应用提供token给客户端  客户端存储token 随后的请求都带着  
服务器校验token并返回数据

每次请求都需要token
Token应该放在请求header中
还需要将服务器设置为接受来自所有域的请求
用Access-Control-Allow-Origin: *
Token好处
无状态和可扩展性
Tokens存储在客户端 完全无状态,可扩展
负载均衡器可以将用户传递到任意服务器,因为在任何地方都没有状态或会话信息
安全Token不是Cookie
The token, not a cookie.
每次请求Token都会被发送。
由于没有Cookie被发送,还有助于防止CSRF攻击。
实现中将token存储到客户端的Cookie中,个Cookie只是存储机制,非身份认证机制。
没有基于会话的信息可以操作,因为没有会话!
token在会过期,用户需要重新登录
token撤销允许根据相同的授权许可使特定的token至一组token无效
JWT与OAuth的区别 OAuth2是授权框架 JWT是认证协议
HTTPS保证数据的安全性
OAuth2用第三方账号登录的情况(比如weibo, qq, github登录某个app)
JWT是用在前后端分离, 需要简单的对后台API进行保护时使用