返回
无感刷新不费力,双token完美实现,后端亲传代码Get!
前端
2023-08-28 19:52:06
无感刷新:双令牌机制的终极指南
什么是无感刷新?
无感刷新是一种前端技术,旨在为用户提供无缝的页面体验。它允许用户在页面上进行操作,无需等待页面重新加载或刷新。这创造了一种类似于单页应用程序的体验,但使用的是传统的多页应用程序模型。
双令牌机制
无感刷新的关键在于双令牌机制。它使用两个不同的令牌:
- 访问令牌 (accessToken) :用于对每个请求进行身份验证。
- 刷新令牌 (refreshToken) :用于请求新的访问令牌。
实现流程
- 用户登录并接收访问令牌和刷新令牌。
- 访问令牌存储在 cookie 中,用于验证后续请求。
- 刷新令牌存储在 localStorage 中,用于在访问令牌过期后获取新的访问令牌。
- 当访问令牌过期时,前端向后端请求新的访问令牌,并使用刷新令牌进行身份验证。
- 后端验证刷新令牌并颁发新的访问令牌。
前端代码(Vue3 + Vite + axios)
安装 axios
npm install axios
创建 axios 实例
import axios from "axios";
const instance = axios.create({
baseURL: "http://localhost:3000",
timeout: 10000,
});
在请求拦截器中添加访问令牌
instance.interceptors.request.use((config) => {
const accessToken = localStorage.getItem("accessToken");
if (accessToken) {
config.headers.Authorization = `Bearer ${accessToken}`;
}
return config;
});
在响应拦截器中处理访问令牌过期
instance.interceptors.response.use(
(response) => {
return response;
},
(error) => {
if (error.response && error.response.status === 401) {
// 访问令牌过期,使用刷新令牌请求新的访问令牌
const refreshToken = localStorage.getItem("refreshToken");
if (refreshToken) {
return instance
.post("/refresh", { refreshToken })
.then((res) => {
// 更新访问令牌和刷新令牌
localStorage.setItem("accessToken", res.data.accessToken);
localStorage.setItem("refreshToken", res.data.refreshToken);
// 重新发送请求
return instance(error.config);
})
.catch((err) => {
// 刷新令牌也过期了,需要重新登录
window.location.href = "/login";
});
} else {
// 刷新令牌也过期了,需要重新登录
window.location.href = "/login";
}
}
return Promise.reject(error);
}
);
后端代码(koa2)
创建 koa2 实例
const Koa = require("koa");
const app = new Koa();
定义登录接口
app.post("/login", async (ctx) => {
const { username, password } = ctx.request.body;
if (username === "admin" && password === "123456") {
const accessToken = jwt.sign({ username }, "secret", { expiresIn: "1h" });
const refreshToken = jwt.sign({ username }, "secret", { expiresIn: "7d" });
ctx.body = { accessToken, refreshToken };
} else {
ctx.status = 401;
ctx.body = "Unauthorized";
}
});
定义刷新访问令牌接口
app.post("/refresh", async (ctx) => {
const { refreshToken } = ctx.request.body;
if (refreshToken) {
const decoded = jwt.verify(refreshToken, "secret");
const accessToken = jwt.sign({ username: decoded.username }, "secret", { expiresIn: "1h" });
ctx.body = { accessToken };
} else {
ctx.status = 401;
ctx.body = "Unauthorized";
}
});
启动 koa2 实例
app.listen(3000);
注意事项
- 访问令牌的有效期应该足够短以确保安全性。
- 刷新令牌的有效期应该足够长以减少向后端请求的次数。
- 将访问令牌和刷新令牌存储在安全的地方以防止被窃取。
- 在前端中使用 axios 库时,务必在请求拦截器中添加访问令牌。
- 在后端中使用 koa2 框架时,务必定义登录和刷新访问令牌的接口。
结论
无感刷新是一种改变用户体验的技术,通过消除页面刷新来提供更加流畅的体验。双令牌机制是实现无感刷新的关键,它允许应用程序在访问令牌过期时在后台无缝地获取新的访问令牌。通过遵循本文中概述的步骤和考虑注意事项,你可以成功地将无感刷新整合到你的应用程序中。
常见问题解答
1. 为什么需要使用双令牌机制?
双令牌机制可以防止单点故障,如果一个令牌被盗用或过期,另一个令牌仍然可用。
2. 访问令牌和刷新令牌的有效期应该有多长?
访问令牌的有效期通常设置为几分钟到几小时,而刷新令牌的有效期可以长达几天或几周。
3. 应该在哪里存储访问令牌和刷新令牌?
访问令牌应该存储在 cookie 中,而刷新令牌应该存储在 localStorage 中。
4. 如何防止访问令牌被盗用?
可以采取多种措施来防止访问令牌被盗用,例如使用安全传输层(SSL/TLS)加密传输,并在服务器端存储令牌而不是客户端。
5. 如何处理刷新令牌也过期的情况?
如果刷新令牌也过期,用户需要重新登录应用程序。