如何解决认证问题是WEB开发的和核心问题,本文重点介绍基于JWT的SSO认证实现思路。
JWT
什么是JWT
JSON Web Token(缩写 JWT)
是一个开放标准(RFC 7519),它定义了一种紧凑且自包含的方式,用于在各方之间安全地将信息作为JSON对象传输。由于此信息是经过数字签名的,因此可以被验证和信任。可以使用秘密(使用HMAC算法)或使用RSA或ECDSA的公用/专用密钥对对JWT进行签名。
JWT的组成
Header.Payload.Signature
JWT 的三个部分用.
分隔,依次是:
Header 部分是一个 JSON 对象,描述 JWT 的元数据,通常是下面的样子
{
"alg": "HS256",
"typ": "JWT"
}
- alg 表示签名的算法(algorithm),默认是 HMAC SHA256(写成 HS256)
- typ表示这个令牌(token)的类型(type),JWT 令牌统一写为JWT
最后将上面的 JSON
对象使用 Base64URL
算法转成字符串
Payload(负载)
Payload 部分也是一个 JSON 对象,用来存放实际需要传递的数据。JWT 规定了7个官方字段,供选用:
- iss (issuer):签发人
- exp (expiration time):过期时间
- sub (subject):主题
- aud (audience):受众
- nbf (Not Before):生效时间
- iat (Issued At):签发时间
- jti (JWT ID):编号
除了官方字段,你还可以在这个部分定义私有字段,下面就是一个例子:
{
"sub": "1234567890",
"name": "John Doe",
"admin": true
}
注意:
- JWT 默认是不加密的,任何人都可以读到,所以不要把秘密信息放在这个部分。
这个 JSON 对象也要使用 Base64URL
算法转成字符串
Signature(签名)
Signature
部分是对前两部分的签名,防止数据篡改。首先,需要指定一个密钥(secret),这个密钥只有服务器才知道,不能泄露给用户。然后,使用 Header
里面指定的签名算法(默认是 HMAC SHA256
),按照下面的公式产生签名。
JWT的使用方式
客户端收到服务器返回的JWT
,可以储存在:
此后,客户端每次与服务器通信,都要带上这个JWT
。其中放在Cookie
里面自动发送,但是不能跨域。也可以放到Http Basic Auth 介绍,如下:
Authorization: Bearer <token>
JWT的特点
- JWT 默认是不加密,不加密的情况下,不能将秘密数据写入 JWT
- JWT 不仅可以用于认证,也可以用于交换信息
- JWT 本身包含了认证信息,存在泄漏风险,使用时建议采用
HTTPS
协议 - JWT 一旦签发了,在到期之前就会始终有效,服务器端需要考虑吊销方式
JWT的使用场景
- 一次性验证,如邮箱验证
- RESTful api的无状态认证
- 单点登录
- 会话管理
使用时需要注意的点
- 服务器在返回客户端
JWT
时,建议给客户端时设置httpOnly=true
并且使用Cookie
而不是LocalStorage
存储JWT - 需要考虑修改密码后,JWT没有及时回收的问题
- JWT续签问题
使用JWT设计单点登录系统
使用cookie
+jwt
的设计非跨域的单点登录是一个不错的方案