type
status
date
slug
summary
tags
category
icon
password

JWT

0 什么是 SSO

SSO(Single Sign On),中文翻译为单点登录,它是目前流行的企业业务整合的解决方案之一,SSO 的目标是在多个应用系统中,用户只需要登录一次就可以访问所有相互信任的应用系统,使用 SSO 整合后,只需要登录一次就可以进入多个系统,而不需要重新登录,这不仅仅带来了更好的用户体验,更重要的是降低了安全的风险和管理的消耗。
  • 为什么要用 SSO?
    • 现在流行的 Web 系统不断变的复杂,从最早的单系统单模块发展到现在的多系统多模块的应用群,用户在访问这些子系统或者分系统的时候,如果有 N 多个系统都要分别登录和登出,用户可能会疯掉。用户希望的是在这些系统中统一的登录和登出,换句话说,不管登录哪个系统之后,其他子系统就无需再登录了。
      举个实际应用的例子,比如微软的各个子系统,你会发现在浏览器不删除 Cookie 的情况下,登录官网后,再访问 OneDrive 是无需再登录的,这种方式就是单点登录 SSO 的应用。
      要实现单点登录,方式有很多,原理也名不相同,在这里主要讲主流的方案:使用 JWT 实现单点登录。
  • 前端用什么保存?
    • Cookie,Sessionstorage,Localstorage

1 什么是 JWT

JSON Web Token 令牌 (JWT) 是一种开放标准(RFC 7519) 它定义了一种紧凑且自包含的方式,用于在各方之间作为 JSON 对象安全地传输信息,此信息可以验证和信任,因为它是经过数字签名的。JWT 可以使用密钥(使用 HMAC 算法)或使用 RSA 或 ECDSA 的公钥/私钥对进行签名,
通俗的说: JSON Web Token 简称即 JWT,也就是通过 JSON 形式的数据作为 Web 应用的令牌,用于在各方之间安全地将信息作为 JSON 对象传输。在数据传输过程中还可以完成数据加密,签名等相关处理。

2 JWT 工作流程

Authorization(授权):这是使用 JWT 的最常见场景。一旦用户登录,后续每个请求都将包含 JWT,允许用户访问该令牌允许的路由、服务和资源。
流程上是这样的:
  1. 用户使用用户名密码来请求服务器
  1. 服务器进行验证用户的信息
  1. 服务器通过验证发送给用户一个 token
  1. 客户端存储 token,并在每次请求时携带上这个 token 值
  1. 服务端验证 token 值,并返回数据

3 JWT 长什么样

JWT 是由三段信息构成的,将这三段信息文本用.链接一起就构成了 JWT 字符串。就像这样:

3.1 第一部分我们称它为头部 (header)

JWT 的头部承载两部分信息:
  • 声明类型,这里是 jwt
  • 声明加密的算法,通常直接使用 HMAC SHA256
完整的头部就像下面这样的 JSON:
然后将头部进行 base64 加密,构成了第一部分:eyJOeXAioiJKV1QiLCJhbGcioiJIUzIINi]9

3.2 第二部分我们称其为载荷 (payload,类似于飞机上承载的物品)

载荷就是存放有效信息的地方。这个名字像是特指飞机上承载的货品,这些有效信息包含三个部分。
  • 标准注册的声明
  • 公共的声明
  • 私有的声明
标准中注册的声明(建议但不强制使用):
  • iss: jwt 签发者
  • sub: jwt 所面向的用户
  • aud: 接收 jwt 的一方
  • exp: jwt 的过期时间,这个过期时间必须要大于签发时间
  • nbf: 定义在什么时间之前,该 jwt 都是不可用的
  • iat: jwt 的签发时间
  • jti: jwt 的唯一身份标识,主要用来作为一次性 token,从而回避重放攻击
公共的声明:公共的声明可以添加任何的信息,一般添加用户的相关信息或淇他业务需要的必要信息但不建议添加敏感信息,因为该部分在客户端可解密。
私有的声明:私有声明是提供者和消费者所共同定义的声明,一般不建议存放敏感信息,因为 bas64 是对称解密的,意味着该部分信息可以归类为明文信息。
定义一个 patload:用户信息
然后将其进行 base64 加密,得到 jwt 的第二部分:ey]zdWIioiIxM jMONTY30DkwIiwibmFtZSI6IkpvaG4gRG91IiwiYWRtaw4ionRydwv9

3.3 第三部分是签证 (signature),

jwt 的第三部分是一个签证信息,这个签证信息由三部分组成:
  • header(base64 后的)
  • payload(base64 后的)
  • secret(盐)
这个部分需要 base64 加密后的 header 和 base64 加密后的 payload 使用 . 连接组成的字符串,然后通过 headere 中声明的加密方式进行加盐 secret 组合加密,然后 就构成了 jwt 的第三部分。
注意:secret 是保程在服务器端的,jwt 的签发生成也是在服务器端的,secret 就是用来进行 jwt 的签发和 jwt 的验证,所以,它就是你服务端的私钥,在任何场景都不应该流露出去。一旦客户端得知这个 secret,那就意味着客户端是可以自我签发 jwt 了。

补充:为什么JWT更适合分布式系统?

补充:Hutool工具包生成JWT

ThreadLocal事务隔离级别
Loading...