Life is too short to waste a second

浅谈验证机制 Cookie Token JWT

Cookie

这里的 Cookie 泛指通过 session ID 验证,用户登录后服务器生成 session ID 并返回给客户端,客户端通过 Cookie 存储 session ID 并在请求资源时携带,服务器查看 session ID 是否存在即可判断用户。
失效:用户登出或到达过期时间,服务器删除 session ID。

Token

这里的 Token 泛指通过存储 Token 验证,和 Cookie 类似,不过服务器不再生成 session ID 而是生成一段加密内容返回给客户端,客户端可以在 Cookie 中或者请求中携带此加密内容,服务端收到后查询数据库(通常是数据库) Token 是否匹配即可判断用户。Token 的实现也可以基与 Cookie,所以我们上面提到的 Cookie 是指基于 session ID 的验证模式。
失效:用户再次登陆或注销,服务器更新 Token,原 Token 失效;Token 到达过期时间,服务器拒绝验证。
Token 本来设计还是无状态的,不过可以通过存储实现有状态,Token 也可以不存储直接解密验证,和 JWT 一样的原理。

JWT

JWT(Json Web Token) 顾名思义,是 Token 的一种实现方式,具体内容可以在网上查到,和存储的 Token 相比,服务端在收到加密内容后是使用自己的密钥解密获取信息,不再需要查询数据库。JWT 是无状态的,如果使用它进行有状态的验证,便失去了其优势。例如,在用户注销后 JWT 仍然是可用的。
失效:如果不做处理特殊将永久生效。

对比

占用服务端资源:

Cookie:服务器内存
Token(存储式):数据库/Redis
JWT:解密计算

客户端存储位置:

Cookie:Cookie
Token:Cookie, localStorage, sessionStorage
JWT:Cookie, localStorage, sessionStorage

安全

注意:无论何种验证方式,都不要将密码等隐私内容存储在客户端,通常存储UID等标识符
注意:无论何种验证方式,放在客户端都不是绝对安全的,不要赋予过高权限

Cookie 可以设置 httpOnly 和 secure 有效防止 XSS 注入,XSS 注入即通过JS代码获取 Cookie 并请求资源
Cookie 存在 CSRF 风险,在现代游览器中可以通过设置 SameSite 属性防止,CSRF 即通过其他网站发送携带 Cookie 的请求到被攻击网站
localStorage, sessionStorage 无法防止 XSS 注入,攻击者可使用JS代码获取你的 Token 并进行攻击
localStorage, sessionStorage 不存在 CSRF 风险,因为它是通过附加到请求参数中实现的

总结

Cookie-Session 验证目前仍有大量使用,但其使用服务器内存,如果人数过大需要考虑内存容量。Token 验证一般在数据库中存值,并不需要占用内存,其可以灵活的放置在 Cookie 或 localStorage 中。JWT 是 Token 中设计比较好的方式,无需在数据库中存值,只需要验证客户端发送的内容即可,对服务器来说只增加了解密计算,同时分布式服务器也无需其它配置,在确认客户端真实后,可以确认客户端携带的 payload 是有效的,便可直接使用 payload 的信息。正如其名, JWT 逐渐在 Web 中使用并替代 传统的Token,JWT 可以存在Cookie中,要注意 CSRF 攻击。也可以存在localStorage中,要注意 XSS 注入。若项目不大,使用 Cookie 或 存储式 Token 也是很好的解决方案。

发表评论

电子邮件地址不会被公开。