Reactjs 中的刷新令牌实现
在本教程中,您将学习如何在 React 应用程序中使用刷新令牌来维护对用户资源的访问权限。刷新令牌允许应用程序获取新的访问令牌,而无需用户重新进行身份验证,这使得它成为长期运行或后台应用程序的实用工具。请跟随我们逐步了解如何在 React 中实现刷新令牌功能。
您可以查看我之前关于Node.js 中刷新令牌实现的帖子
👋 您还可以在Linkedin上查看我的每周帖子
要求
- React.js 的基础知识。
- axios 的基础知识。
首先,在你的 React 应用中创建一个新文件,你可以将其命名为“axios.js”,并将其放置在“helpers”文件夹中,或者你应用中的任何其他位置。此文件将用于使用 axios 库设置和自定义应用的 HTTP 请求,并包含刷新令牌实现的所有逻辑。整个过程很简单,让我们开始吧!
从以下开始:
const customFetch = axios.create({
baseURL: "http://localhost:3000/api/",
headers: {
"Content-type": "application/json",
},
withCredentials: true,
});
此代码创建具有特定配置的 axios 库的自定义实例。
- baseURL字段设置此实例将用于调用的所有 API 端点的基本 URL。在本例中,它设置为“ http://localhost:3000/api/ ”。
- 标头对象定义了使用此实例发出的每个请求中发送的默认标头。
- withCredentials是一个布尔值,用于指示是否在请求中发送“Cookie”标头。设置为 true 时,每次请求都会发送“Cookie”标头。
您可以使用此自定义 axios 实例,以与默认 axios 对象相同的方式发出 HTTP 请求。使用此自定义实例的主要优势在于,它包含此代码中指定的默认配置,因此您不必在每个请求中都包含这些选项。
▪️ 需要澄清的是,还可以添加此拦截器,以便从本地存储中检索 accessToken 并将其包含在请求的授权标头中。
customFetch.interceptors.request.use(
async (config) => {
const token = getTokenFromLocalStorage();
if (token) {
config.headers["Authorization"] = ` bearer ${token}`;
}
return config;
},
(error) => {
return Promise.reject(error);
}
);
现在我们将重点关注本博客的关键部分:下面的代码负责通过使用刷新令牌向服务器发送请求并在响应中接收新的访问令牌来刷新访问令牌。
const refreshToken = async () => {
try {
const resp = await customFetch.get("auth/refresh");
console.log("refresh token", resp.data);
return resp.data;
} catch (e) {
console.log("Error",e);
}
};
这是一个使用 axios 的 customFetch 实例向“auth/refresh”端点发送 GET 请求的函数。如果请求成功,该函数会将响应数据记录到控制台并返回。如果请求失败,该函数会将错误记录到控制台。
▪️今天重要的拦截器是下面的代码:
customFetch.interceptors.response.use(
(response) => {
return response;
},
async function (error) {
const originalRequest = error.config;
if (error.response.status === 403 && !originalRequest._retry) {
originalRequest._retry = true;
const resp = await refreshToken();
const access_token = resp.response.accessToken;
addTokenToLocalStorage(access_token);
customFetch.defaults.headers.common[
"Authorization"
] = `Bearer ${access_token}`;
return customFetch(originalRequest);
}
return Promise.reject(error);
}
);
拦截器函数接受两个参数:一个包含响应数据的响应对象,以及一个用于在响应被拒绝时返回的错误对象。该函数返回响应对象,或者返回一个包含错误对象的被拒绝的 Promise。
拦截器首先检查响应的状态是否为 403(禁止访问),以及原始请求的 _retry 属性是否未设置。如果两个条件都满足,则将 _retry 属性设置为 true,并调用 refreshToken 函数尝试刷新访问令牌。如果刷新成功,新的访问令牌将添加到本地存储,并使用新令牌更新 customFetch 实例的 Authorization 标头。然后,使用更新后的 customFetch 实例重试原始请求。如果刷新不成功,或者原始响应的状态不是 403,则拦截器返回一个带有错误对象的被拒绝的 Promise。
此拦截器将在 axios 的 customFetch 实例收到的每个响应时被调用,并且如果访问令牌已过期且服务器返回 403 状态代码,则会尝试刷新访问令牌并重试请求。
总结:在本教程中,我们学习了如何在 React 应用程序中使用刷新令牌来维护对用户资源的访问权限。我们设置了一个自定义的 axios 库实例,并对其进行了特定的配置,其中包括一个拦截器,用于在每个请求中添加一个带有持有者令牌的授权标头。我们还实现了另一个拦截器,用于通过尝试刷新令牌并重试原始请求来处理过期的访问令牌。借助这些技术,我们可以保持应用程序的身份验证,并维护对用户资源的访问权限,而无需用户持续提供其登录凭据。
文章来源:https://dev.to/chafroudtarek/refresh-token-implementation-in-reactjs-53f7