Access Token 存储在 LocalStorage 安全吗?遇到跨域请求被泄露怎么办?
我在做用户登录功能时把 Access Token 放在了 LocalStorage,但测试跨域请求时突然出现错误:“Failed to load resource: Preflight response is not successful”。折腾了一下午,发现后端 CORS 配置没问题,但每次请求头里都没有带 Token,这是不是说明 Token 被泄露了?
我的登录成功后这样存储的:
const handleLogin = () => {
axios.post('/api/login', { username, password })
.then(res => {
localStorage.setItem('authToken', res.data.token);
axios.defaults.headers.common['Authorization'] = <code>Bearer ${res.data.token}</code>;
});
};
后来改用 sessionStorage 问题依旧,难道只能用 HttpOnly 的 Cookie?但前端又拿不到 Cookie 值发请求啊…是不是我的存储方式根本就有问题?
你的问题其实有两个方面:一个是 Token 存储的安全性,另一个是跨域请求的问题。
首先说存储方式。LocalStorage 完全不建议存敏感信息,因为它容易被 XSS 攻击拿到。SessionStorage 也差不多,只是生命周期短点。血泪教训啊,我之前项目就因为这个被安全团队批得不行。
HttpOnly Cookie 是个好选择,虽然前端拿不到值,但你可以让后端设置 SameSite=None; Secure 这样的属性,这样在跨域请求时会自动带上 Cookie。你只需要在登录接口返回 Set-Cookie 头就行。
关于跨域请求的问题,你遇到的错误提示是因为 OPTIONS 预检请求没通过。这和 Token 泄露没关系,检查一下服务器的 CORS 配置,确保它允许你的前端域名访问,并且支持 Authorization 头。
给你一个简单的例子:
记得前后端都要配置 CORS,后端要允许 Credentials 和 Authorization 头。折腾一下午不容易,希望这些经验能帮你少走弯路。
这样每次请求都会自动带上 token,CORS 才不会失败。至于安全,防 XSS 比纠结存储位置更重要,真怕泄露就上 HttpOnly + SameSite 严格模式。搞定。