马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有账号?立即注册
×
在前端开辟中,Token 无感革新是一种常见的优化技能,用于在用户无感知的环境下革新逾期的身份验证 Token,从而制止用户因 Token 逾期而须要重新登录。以下是实现 Token 无感革新的思绪和详细实现方法。
实现思绪
Token 逾期机制:
通常,身份验证 Token 有一个有用期(如 2 小时)。
当 Token 逾期后,用户须要重新登录或革新 Token。
无感革新的核心:
在 Token 逾期前,通过革新 Token 接口获取新的 Token。
利用新的 Token 更换旧的 Token,并继承用户的哀求。
实现步调:
在哀求拦截器中查抄 Token 是否即将逾期。
如果 Token 即将逾期,发起革新 Token 的哀求。
在相应拦截器中处理处罚 Token 逾期的环境,重新发起失败的哀求。
详细实现
以下是一个基于 Axios 的 Token 无感革新实现示例:
- 安装 Axios
如果尚未安装 Axios,可以通过以下下令安装:
- 封装 Axios 实例
创建一个封装了 Token 无感革新逻辑的 Axios 实例。
- import axios from "axios";
- // 创建 Axios 实例
- const instance = axios.create({
- baseURL: "https://api.example.com",
- timeout: 10000,
- });
- // 存储 Token 和刷新 Token
- let token = localStorage.getItem("token") || "";
- let refreshToken = localStorage.getItem("refreshToken") || "";
- // 请求拦截器
- instance.interceptors.request.use(
- (config) => {
- // 如果 Token 存在,添加到请求头
- if (token) {
- config.headers.Authorization = `Bearer ${token}`;
- }
- return config;
- },
- (error) => {
- return Promise.reject(error);
- }
- );
- // 响应拦截器
- instance.interceptors.response.use(
- (response) => {
- return response;
- },
- async (error) => {
- const originalRequest = error.config;
- // 如果 Token 过期且未发起过刷新请求
- if (error.response.status === 401 && !originalRequest._retry) {
- originalRequest._retry = true; // 标记为已发起刷新请求
- try {
- // 发起刷新 Token 的请求
- const response = await axios.post("/refresh-token", {
- refreshToken,
- });
- // 更新 Token 和刷新 Token
- const { token: newToken, refreshToken: newRefreshToken } = response.data;
- token = newToken;
- refreshToken = newRefreshToken;
- localStorage.setItem("token", newToken);
- localStorage.setItem("refreshToken", newRefreshToken);
- // 更新请求头中的 Token
- originalRequest.headers.Authorization = `Bearer ${newToken}`;
- // 重新发起原始请求
- return instance(originalRequest);
- } catch (refreshError) {
- // 刷新 Token 失败,跳转到登录页
- localStorage.removeItem("token");
- localStorage.removeItem("refreshToken");
- window.location.href = "/login";
- return Promise.reject(refreshError);
- }
- }
- return Promise.reject(error);
- }
- );
- export default instance;
复制代码
- 利用封装的 Axios 实例
在项目中利用封装好的 Axios 实例发起哀求。
- import axiosInstance from "./axiosInstance";
- const fetchData = async () => {
- try {
- const response = await axiosInstance.get("/data");
- console.log(response.data);
- } catch (error) {
- console.error("请求失败", error);
- }
- };
- fetchData();
复制代码 关键点分析
Token 存储:
将 Token 和革新 Token 存储在 localStorage 或 sessionStorage 中。
每次哀求时从存储中读取 Token。
哀求拦截器:
在哀求拦截器中,将 Token 添加到哀求头。
相应拦截器:
在相应拦截器中,查抄相应状态码是否为 401(未授权)。
如果 Token 逾期,发起革新 Token 的哀求。
革新乐成后,更新 Token 并重新发起原始哀求。
革新 Token 接口:
后端须要提供一个革新 Token 的接口(如 /refresh-token),罗致 refreshToken 并返回新的 token 和 refreshToken。
错误处理处罚:
如果革新 Token 失败,打扫当地存储的 Token 并跳转到登录页。
进一步优化
Token 逾期时间查抄:
在哀求拦截器中查抄 Token 的剩余有用期。
如果 Token 即将逾期(如剩余 5 分钟),提前革新 Token。
- const isTokenExpired = (token) => {
- const payload = JSON.parse(atob(token.split(".")[1]));
- const exp = payload.exp * 1000; // 转换为毫秒
- return Date.now() >= exp - 5 * 60 * 1000; // 提前 5 分钟刷新
- };
- instance.interceptors.request.use(
- (config) => {
- if (token && isTokenExpired(token)) {
- // 发起刷新 Token 的请求
- refreshToken()
- .then((newToken) => {
- token = newToken;
- localStorage.setItem("token", newToken);
- config.headers.Authorization = `Bearer ${newToken}`;
- })
- .catch(() => {
- localStorage.removeItem("token");
- window.location.href = "/login";
- });
- }
- return config;
- },
- (error) => {
- return Promise.reject(error);
- }
- );
复制代码 并发哀求处理处罚:
如果多个哀求同时发现 Token 逾期,确保只发起一次革新 Token 的哀求。
利用一个标志变量(如 isRefreshing)来控制革新哀求的并发。
安全性:
利用 HTTPS 加密传输 Token。
设置公道的 Token 有用期和革新 Token 的有用期。
总结
通过 Axios 的哀求拦截器和相应拦截器,可以实现 Token 的无感革新,从而提拔用户体验。关键在于:
在 Token 逾期前主动革新。
处理处罚并发哀求和错误环境。
确保 Token 存储和传输的安全性。
这种方法实用于大多数前后端分离的项目,可以大概有用镌汰用户因 Token 逾期而须要重新登录的环境。
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
|