JWT 原理描述
当你登录一个网站或者应用时,服务器会验证你的用户名和密码。如果验证成功了,服务器就会生成一个JWT通行证,然后返回给你。你可以把这个通行证保存在你的浏览器里,比如localStorage或者sessionStorage。
以后,你每次向服务器请求资源时,都要带上这个JWT通行证。服务器收到请求后,就会验证这个通行证的有效性。它会检查通行证的签名是否正确,有没有过期,还有接收方是不是自己。如果都验证通过了,服务器就会认为你是合法的用户,然后处理你的请求。
JWT 构成
Header
header 典型的由两部分组成:token 的类型(JWT)和算法名称(HMAC、SHA256、RSA 等)
1{2 "alg": "HS256",3 "typ": "JWT"4}通过 Base64 对这个 JSON 编码就得到 JWT 的第一部分。
Payload
它包含关于实体(通常是用户)和其他数据的声明(Claims),分别是 Registered、Public 和 Private 三种类型。
-
Registered claims: 预定义的声明,它们不是强制的,但是推荐。如:iss (issuer)、exp (expiration time)、sub (subject)、aud (audience) 等
-
Public claims : 可随意定义
-
Private claims : 用于在同意使用它们的各方之间共享信息
1{2 "sub": "1234567890",3 "name": "John Doe",4 "iat": 15162390225}通过 Base64 对这个 JSON 编码就得到 JWT 的第二部分。
Signature
Signature 用来验证发送请求者身份,由前两部分加密形成。
1var hs256 = new HMACSHA256(Encoding.ASCII.GetBytes(securityKey));2var encodedSignature = Base64UrlEncoder.Encode(hs256.ComputeHash(Encoding.UTF8.GetBytes(string.Concat(encodedHeader, ".", encodedPayload))));Token 过期
- 登录后把账号密码记录在浏览器中,自动登录。但基于安全考虑,一般是用户特别勾选“记住我”,才会加密记录账号密码到 localstorage 中,用户下次打开浏览器时自动登录。如果 token 过期就自动登录,如何及时止损?后台修改密码或禁用账号,如何同步到前端的 localstorage 中。大部分 app 是这么干的。以上 3 种都是要再次去后台数据库验证,所以 token 过期时间不能太短,否则效率很差。
- 设置 refresh-token 机制,颁发 access-token 时同时颁发一个 refresh-token,唯一区别是 refresh-token 有效期比较长,比如 1 个月。当 access-token 过期后,拿着 refresh-token 到后台换取新的 access-token。通过在后台为 refresh-token 设置黑名单来及时止损,所以有黑名单的时候,可能效率也会一样的差。refresh-token 也过期后,那就只有老老实实的让用户输入账号密码登录了,就是前面的 1,2 方法。因为 refresh-token 不常用,所以最好不要放在 cookie 中避免每次自动传到后台,放在 localstorage 较好。