Lev*_*kov 5 interceptor http-headers typescript reactjs axios
我遇到了一个非常奇怪的问题,实现 axios 拦截器来处理过期的令牌并刷新它。
\n我正在使用访问和刷新令牌实施 JWT 身份验证。
\n当请求发送到需要 JWT 身份验证的 API 路由时,请求拦截器会确保标头包含带有不记名令牌的授权。响应拦截器检查是否需要新的访问令牌,发送刷新请求,最后使用新配置更新 axios 实例。
\n我按照 Dave Gray 的视频编写了代码,但使用了 TypeScript。
\n测试此代码时,我将刷新令牌生存期设置为非常长,同时将访问令牌生存期设置为 5 秒。过期后,当对受保护路由的请求发生时,一切都按照计划进行\xe2\x80\x94来自后端的日志包含两个成功完成的请求:(1)到带有 401 响应的受保护路由,然后(2 ) 刷新请求。
\n此时,我在浏览器控制台(Chrome 和 Safari)中看到 DOMException,它指出setRequestHeader由于源代码函数不是有效的标头值而无法执行。当然,事实并非如此!这段代码是这样的。
const axiosPrivate = axios.create({\n baseURL: BASE_URL,\n headers: { "Content-Type": "application/json" },\n withCredentials: true,\n});\n\ninterface IRequestConfig extends AxiosRequestConfig {\n sent?: boolean;\n}\n\nconst useAxiosPrivate = () => {\n const { auth } = useAuth()!;\n const refresh = useRefreshToken();\n\n React.useEffect(() => {\n const requestInterceptor = axiosPrivate.interceptors.request.use(\n (config: AxiosRequestConfig) => {\n config.headers = config.headers ?? {};\n if (!config.headers["Authorization"]) {\n config.headers["Authorization"] = `Bearer ${auth?.token}`;\n }\n return config;\n },\n async (error: AxiosError): Promise<AxiosError> => {\n return Promise.reject(error);\n }\n );\n\n const responseInterceptor = axiosPrivate.interceptors.response.use(\n (response: AxiosResponse) => response,\n async (error: AxiosError): Promise<AxiosError> => {\n const prevRequestConfig = error.config as IRequestConfig;\n if (error?.response?.status === 401 && !prevRequestConfig?.sent) {\n const newAccessToken = await refresh();\n prevRequestConfig.sent = true;\n prevRequestConfig.headers = prevRequestConfig.headers!;\n prevRequestConfig.headers[\n "Authorization"\n ] = `Bearer ${newAccessToken}`;\n return axiosPrivate(prevRequestConfig);\n }\n return Promise.reject(error);\n }\n );\n\n return () => {\n axiosPrivate.interceptors.request.eject(requestInterceptor);\n axiosPrivate.interceptors.response.eject(responseInterceptor);\n };\n }, [auth, refresh]);\n\n return axiosPrivate;\n};\nRun Code Online (Sandbox Code Playgroud)\nDOMException: Failed to execute \'setRequestHeader\' on \'XMLHttpRequest\': \'function (header, parser) {\n header = normalizeHeader(header);\n if (!header) return undefined;\n const key = findKey(this, header);\n\n if (key) {\n const value = this[key];\n\n if (!parser) {\n return value;\n }\n\n if (parser === true) {\n return parseTokens(value);\n }\n\n if (_utils_js__WEBPACK_IMPORTED_MODULE_0__["default"].isFunction(parser)) {\n return parser.call(this, value, key);\n }\n\n if (_utils_js__WEBPACK_IMPORTED_MODULE_0__["default"].isRegExp(parser)) {\n return parser.exec(value);\n }\n\n throw new TypeError(\'parser must be boolean|regexp|function\');\n }\n }\' is not a valid HTTP header field value.\nRun Code Online (Sandbox Code Playgroud)\n到目前为止,我只在互联网上 发现了一个类似的问题,其中有其他一些问题的链接。其中之一axios给了我一个提示,这可能是如何读取 axios 实例的配置的问题。
我不确定问题是否确实出在 axios 的某个地方。如果您对这个问题有任何有用的想法,我将非常感激!
\naxiosPrivate不是 来解决它axiosPrivate(prevRequestConfig)。const responseIntercept = axiosPrivate.interceptors.response.use(
response => response,
async (error)=>{
const prevRequest = error?.config;
if (error?.response?.status === 403 && !prevRequest?.sent){
const newAccessToken = await refresh();
// console.log(prevRequest);
return axiosPrivate({
...prevRequest,
headers: {...prevRequest.headers, Authorization: `Bearer ${newAccessToken}`},
sent: true
});
}
return Promise.reject(error);
}
);
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2864 次 |
| 最近记录: |