安全认证模式
令牌存储(内存、localStorage 或 httpOnly Cookie)、静默刷新,以及标签页关闭时退出登录
安全认证模式 是 CoddyKit 上的免费 Vue Academy 课时。 这是第 4 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 Vue Academy 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 Vue Academy 课程共包含 4 节课。
token 及其存放位置
单页应用(SPA)使用 token 进行身份验证,但 token 的存放位置决定了您面临的 XSS 和 CSRF 风险。现代做法是将短期访问令牌与长期刷新令牌分开,并以不同方式存储。
localStorage 的问题
将 token 存储在 localStorage 中很方便,但也很危险:任何由 XSS 注入的脚本都可以读取它并将 token 泄露出去。请避免将凭据放在那里。
// AVOID
localStorage.setItem("token", accessToken);将访问令牌存放在内存中
将访问令牌保存在 JavaScript 变量或响应式 ref 中。重新加载页面后它就会消失,因此即使发生 XSS,攻击者可利用的时间窗口也会小得多,并且磁盘上不会留下任何持久数据。
import { ref } from "vue";
export const accessToken = ref(null);将刷新令牌存放在 httpOnly Cookie 中
刷新令牌存放在带有 HttpOnly、Secure 和 SameSite 属性的 Cookie 中。JavaScript 无法读取它,因此 XSS 无法窃取它,而且浏览器只会将它发送到您的身份验证端点。
Set-Cookie: refresh=...; HttpOnly; Secure; SameSite=Strict; Path=/auth附加访问令牌
Axios 请求拦截器会在每次调用中,将内存中的访问令牌添加到 Authorization 标头。
api.interceptors.request.use((config) => {
if (accessToken.value) {
config.headers.Authorization = "Bearer " + accessToken.value;
}
return config;
});检测过期:401
访问令牌过期后,服务器会返回 401 Unauthorized。响应拦截器会捕获这个响应并触发刷新操作。
api.interceptors.response.use(
(res) => res,
async (error) => {
if (error.response?.status === 401) {
// attempt refresh
}
return Promise.reject(error);
}
);刷新 token
收到 401 后,调用刷新端点。浏览器会自动发送 httpOnly 刷新 Cookie(withCredentials),服务器则返回新的访问令牌。
const { data } = await axios.post("/auth/refresh", null, {
withCredentials: true
});
accessToken.value = data.accessToken;重试 original 请求
完成 refreshing 后,使用新令牌重新发送失败的 original 请求,让用户完全察觉不到。
async (error) => {
const original = error.config;
if (error.response?.status === 401 && !original._retry) {
original._retry = true;
const { data } = await axios.post("/auth/refresh", null, { withCredentials: true });
accessToken.value = data.accessToken;
original.headers.Authorization = "Bearer " + data.accessToken;
return api(original);
}
return Promise.reject(error);
}避免刷新请求风暴
如果许多请求同时返回 401,请将它们排在同一个正在进行的刷新请求之后,避免反复触发刷新端点。
let refreshing = null;
function refresh() {
if (!refreshing) {
refreshing = axios.post("/auth/refresh", null, { withCredentials: true })
.finally(() => { refreshing = null; });
}
return refreshing;
}退出登录
退出登录时,清除内存中的令牌,并调用一个在服务器端清除刷新 Cookie 的端点。
async function logout() {
accessToken.value = null;
await axios.post("/auth/logout", null, { withCredentials: true });
}结合 CSRF 防护
由于刷新 Cookie 会自动发送,请像保护其他通过 Cookie 进行身份验证的路由一样,使用 SameSite 和 CSRF 令牌保护该端点。
快速检查
accessToken 和刷新令牌分别应存储在哪里?
回顾
将 accessToken 存储在内存中的 ref 中(绝不要存入 localStorage),将刷新令牌存储在 HttpOnly Cookie 中。请求拦截器附加持有者令牌;响应拦截器捕获 401,调用刷新端点,更新令牌,并重试 original 请求,同时合并并发刷新请求,配合 CSRF 防护。
用 AI 导师学习 HTML — 免费
在浏览器中编写并运行真实代码,获得全天候 AI 导师的即时帮助,并在网页或应用中继续学习。
- 课程
- 42
- 课程
- 156
常见问题解答
「安全认证模式」课时是免费的吗?
是的 — 「安全认证模式」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 Vue Academy 课程的其余内容,请升级到 CoddyKit PRO。 Vue Academy 课程共包含 4 节课。
「安全认证模式」这节课中我会学到什么?
令牌存储(内存、localStorage 或 httpOnly Cookie)、静默刷新,以及标签页关闭时退出登录 你通过在浏览器中直接运行的动手代码来练习 Vue Academy,全天候 AI 导师会在你学习这节课的过程中回答你的问题。
学习 Vue Academy 需要有经验吗?
无需任何先前经验。CoddyKit 上的 Vue Academy 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 4 节课,共 4 节。
「安全认证模式」课时需要多长时间?
大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。
我能在这节 Vue Academy 课中编写并运行代码吗?
能。每节 Vue Academy 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。