标签 JWT 下的文章

关于前后端分离鉴权的思考

前后端分离项目的 Token 存储问题由来已久,有的人存 Cookie 有的人存 LocalStorage 或 SessionStorage。在之前的个人项目中,曾经花时间去研究这个问题,以下分享下我的看法。

如何安全的传输用户 token

这是最传统也是最简单的方式了,前端登录,后端根据用户信息生成一个 token,并保存这个 token 和对应的用户 id,接着把 token 传给用户,存入浏览器 cookie,之后浏览器请求带上这个 cookie,后端根据这个 cookie 来标识用户。

flow-cookie-session.jpg

但这样做问题就很多,如果我们的页面出现了 XSS 漏洞,由于 cookie 可以被 JavaScript 读取,XSS 漏洞会导致用户 token 泄露,而作为后端识别用户的标识,cookie 的泄露意味着用户信息不再安全。

尽管我们通过转义输出内容,使用 CDN 等可以尽量避免 XSS 注入,但谁也不能保证在大型的项目中不会出现这个问题。另外,后端每次都需要根据 token 查出用户 id,这就增加了数据库的查询和存储开销。

在设置 cookie 的时候,其实你还可以设置 httpOnly 以及 secure 项。设置 httpOnly 后 cookie 将不能被 JS 读取,浏览器会自动的把它加在请求的 header 当中,设置 secure 的话,cookie 就只允许通过 HTTPS 传输。

secure 选项可以过滤掉一些使用 HTTP 协议的 XSS 注入,但并不能完全阻止。

httpOnly 选项使得 JS 不能读取到 cookie,那么 XSS 注入的问题也基本不用担心了。但设置 httpOnly 就带来了另一个问题,就是很容易的被 XSRF,即跨站请求伪造。当你浏览器开着这个页面的时候,另一个页面可以很容易的跨站请求这个页面的内容。因为 cookie 默认被发了出去。

CSRF.jpg

看起来我们不能兼顾。确实,光依靠这一个 token 我们没办法兼顾这两点。既然一个不够,那就两个。于是有了 XSRF-TOKEN,它和作为用户令牌的 token 类似,也是服务器生成的一个散列值。我们把 token 通过 httpOnly 发回去,把 XSRF-TOKEN 直接发回去。我们可以无视 httpOnly 的 cookie 因为我们没法操纵它,但对于这个 XSRF-TOKEN,我们就可以在我们网站的每个请求中都加入到 header 里面去。而服务端就需要检查这个 header 的 XSRF-TOKEN 是否真实有效。

- 阅读剩余部分 -