JWT 应该保存在哪里
参考网址:
https://mp.weixin.qq.com/s/iMjny6ehvr1JZR9nJA3VGQ
前置说明
看这篇文章前 , 我也在考虑这个问题 , gitee 上很多的开源项目, 关于 token 令牌的存放位置 , 每个项目都是有点差异 , 有的存放在 cookie , 有的存放在 LocalStorage , 有的存放在 SessionStorage , 经过本文的阅读 , token 存放在 cookie 是最好的一个方案
Cookie
服务端可以将JWT令牌通过Cookie发给浏览器,浏览器在请求服务端接口时会自动在Cookie头中带上JWT令牌,服务端对Cookie头中的JWT令牌进行检验即可实现身份验证。但它容易受到CSRF攻击的影响。
解决的方法是通过设置Cookie的SameSite
属性为Strict
。跨站时不会发送 Cookie。换言之,只有当前网页的 URL 与请求目标一致,才会带上 Cookie。
Cookie除了易受CSRF攻击还有XSS攻击。黑客可以通过JS脚本读取Cookie中的信息。为了防止这一点,可以设置Cookie的属性为HttpOnly
。
response.setHeader("Set-Cookie", "jwt=jwt_value;Path=/;Domain=domainvalue;Max-Age=seconds;HttpOnly");
你可以通过设置
Max-Age
来设置其生存时间。
localStorage
localStorage也可以存储JWT令牌,这种方法不易受到 CSRF 的影响。但是和Cookie不同的是它不会自动在请求中携带令牌,需要通过代码来实现。不过这样会受到XSS攻击。另外如果用户不主动清除JWT令牌,它将永远存储到localStorage。
sessionStorage
sessionStorage大部分特性类似localStorage,不过它的生命周期不同于localStorage,它是会话级存储。关闭页面或浏览器后会被清除。
总结
您可能会注意到所有 3 种方法都有相同的缺点——“易受 XSS 攻击”。请特别注意 XSS的防护,并始终遵循XSS保护的最佳实践。
结论
三种形式都容易收到XSS攻击,因此如果对安全性要求很高,要特别针对性的配置。在三种方式之中,Cookie 提供了一堆安全选项,例如SameSite
、HttpOnly
等。因此最好使用 Cookie。
项目举例
gitee 上排名靠前的项目 token 存放的位置和对应的源码
ruoyi-vue
官网地址:
https://ruoyi.vip/
ruoyi-vue 前后端分离在线体验地址
http://vue.ruoyi.vip/
源码地址
https://gitee.com/y_project/RuoYi-Vue
对应前端源码
ruoyi-ui/src/utils/request.js
// request拦截器
service.interceptors.request.use(config => {
// 是否需要设置 token
const isToken = (config.headers || {}).isToken === false
// 是否需要防止数据重复提交
const isRepeatSubmit = (config.headers || {}).repeatSubmit === false
if (getToken() && !isToken) {
config.headers['Authorization'] = 'Bearer ' + getToken() // 让每个请求携带自定义token 请根据实际情况自行修改
}
...
找到 getToken() 方法 —> ruoyi-ui/src/utils/auth.js
import Cookies from 'js-cookie'
const TokenKey = 'Admin-Token'
// 获取 token
export function getToken() {
return Cookies.get(TokenKey)
}
// 设置 token
export function setToken(token) {
return Cookies.set(TokenKey, token)
}
export function removeToken() {
return Cookies.remove(TokenKey)
}
TokenKey, token)
}
export function removeToken() {
return Cookies.remove(TokenKey)
}