什么是JSON Web Token?
JSON Web Token(JWT)是一个开放式标准(RFC 7519),它定义了一种紧凑且自包含的方式,用于在各方之间以JSON对象安全传输信息。这些信息可以通过数字签名进行验证和信任。可以使用秘密(使用HMAC算法)或使用RSA的公钥/私钥对对JWT进行签名。

最终的JWT串的样子:
ewogICJhbGciOiAiSFMyNTYiLAogICJ0eXAiOiAiSldUIgp9ICA=.ewogICAgImlzcyI6ICJMZWZ0by5jb20iLAogICAgImlhdCI6IDE1MDAyMTgwNzcsCiAgICAiZXhwIjogMTUwMDIxODA3NywKICAgICJhdWQiOiAid3d3LmxlZnRzby5jb20iLAogICAgInN1YiI6ICJsZWZ0c29AcXEuY29tIiwKICAgICJ1c2VyX2lkIjogImRjMmM0ZWVmZTJkMTQxNDkwYjZjYTYxMmUyNTJmOTJlIiwKICAgICJ1c2VyX3Rva2VuIjogIjA5ZjdmMjVjZGIwMDM2OTljZWUwNTc1OWU3OTM0ZmIyIgp9.Njg2ODU1YzU3ODM2MmU3NjIyNDhmMjJlMmNjMTIxM2RjN2E2YWZmOGViZGE1MjI0Nzc4MGViNmI1YWU5MTg3Nw==

适用场景:
session: 适用于支持cookie协议(RFC6265)的浏览器,可与服务端配合,如果你的程序的客户端运行在浏览器中,可使用session。
JWT: 适用于app,不支持cookie协议的地方。


存储:
session:在客户端存储在cookie中,同时也在服务端存储。常规来说一个tomcat节点可支持2000个session(意思是同时2000用户在线)
JWT:只在客户端存储,一般使用本地存储( localStorage ),不在服务端存储。服务端无存储数量的压力,理论上可支持更多的客户端

用户信息:
session:用户信息存储在服务端的session中。在分布式环境中,用户信息集中存储在redis,使用sessionID为key。
JWT:JWT是一个长长的json串,用户信息存储在其中,这样就不用在服务端有存储。(这是重要特性之一)

状态:
session:有状态
JWT:无状态

失效:
session:可在服务端控制是否失效。可配置过期时间,一般30分钟内无访问就会销毁。
JWT:这是一个严重的问题,由于服务端不存储jwt,所以服务端无法主动控制让jwt失效。在退出登录、修改密码时怎样实现JWT Token失效是一个问题(请看最后)。jwt中存储一个过期时间值,可定期失效,但引出jwt如何更新的问题。

续命:
session:客户端每访问服务端一次,就会为session续命,赋予新的30分钟有效期。
JWT:不知道怎么续命,永久有效?一个月有效?

防盗取:
session:如果有人盗取了你的sessionID,就可顶替你登录系统了。
JWT:如果有人盗取了你的jwt,就可顶替你登录系统了。
解决:使用https

跨域:
session:跨域无法携带cookie,请求http接口时,浏览器默认只让携带本域下的cookie。
JWT:由客户端本地存储jwt ( localStorage ),请求任何域的http接口都可手工携带jwt。


--------------------------------
有以下几个方法可以做到失效 JWT token:( 没有一个方案是理想的 )

1、将 jwt 存入 DB(如 Redis)中,失效则删除;但增加了一个每次校验时候都要先从 DB 中查询 token 是否存在的步骤,而且违背了 JWT 的无状态原则(这不就和 session 一样了么?)。
2、维护一个 jwt 黑名单,失效则加入黑名单中。
3、在 JWT 中增加一个版本号字段,失效则改变该版本号。
4、在服务端设置加密的 key 时,为每个用户生成唯一的 key,失效则改变该 key。


总结:在开发app时,登录状态的保存与传递 ,使用jwt并不是一个好方案,不选择jwt。