gpt4 book ai didi

javascript - 如果使用 axios 刷新 token 已过期,则正确重定向用户

转载 作者:行者123 更新时间:2023-11-29 18:46:19 24 4
gpt4 key购买 nike

我在项目的前端使用 Axios,需要一种方法将用户重定向到登录页面,以防他想使用过期的 token (刷新 token 对后端无效),我在上找到了一个 boilerplate code看起来很容易适应我的技术堆栈的网络(没有 Redux 的 ReactJS):

import axios from 'axios';

// additional code that lives in its own module
const getToken = () => {
return isAuth() ? window.localStorage.getItem("token") : "";
};

const getRefreshToken = () => {
return isAuth() ? window.localStorage.getItem("refresh_token") : "";
};

const setTokens = (token, refresh) => {
window.localStorage.setItem("token", token);
window.localStorage.setItem("refresh_token", refresh);
};
// this is on my app.js file
axios.interceptors.response.use(function (response) {
return response;
}, function (error) {
const originalRequest = error.config;
if (error.response.status === 401 && !originalRequest._retry) {
originalRequest._retry = true;
// Hace la solicitud de refresco de tokens
return axios.get('/api/v1/auth', {headers: {'Authorization': 'Bearer ' + getRefreshToken()}})
.then((responseData) => {
// actualiza la información de OAuth
setTokens(responseData.data.access_token, responseData.data.refresh_token);
axios.defaults.headers.common['Authorization'] = 'Bearer ' + getToken();
originalRequest.headers['Authorization'] = 'Bearer ' + getToken();
// re-intenta la solicitud original
return axios(originalRequest);
}).catch(function (error) {
console.log(error);
setTokens(undefined, undefined);
window.location.pathname = "/login";
});
}
return Promise.reject(error);
});

问题在于代码进入无限递归,导致前端无法使用。如果我手动导航到 /login,递归将完全停止。

编辑

这是文件的完整源代码,我只需要根据我的问题接受的解决方案进行更改:

import React, { Component } from 'react';
import createHistory from 'history/createBrowserHistory';
import {Router} from 'react-router';

import Fero from './containers/Fero/Fero';
import {setTokens, getRefreshToken, getToken} from './utils/auth';

import axios from 'axios';

const myhistory = createHistory();


axios.interceptors.response.use(function (response) {
return response;
}, function (error) {
const originalRequest = error.config;
if (error.response.status === 401 && !originalRequest._retry) {
originalRequest._retry = true;
// Hace la solicitud de refresco de tokens
return axios.get('/api/v1/auth', {headers: {'Authorization': 'Bearer ' + getRefreshToken()}})
.then((responseData) => {
// actualiza la información de OAuth
setTokens(responseData.data.access_token, responseData.data.refresh_token);
axios.defaults.headers.common['Authorization'] = 'Bearer ' + getToken();
originalRequest.headers['Authorization'] = 'Bearer ' + getToken();
// re-intenta la solicitud original
return axios(originalRequest);
}).catch(function (error) {
console.log(error);
setTokens(undefined, undefined);
myhistory.replace("/login");
});
}
return Promise.reject(error);
});

class App extends Component {
render() {
return (
<Router history={myhistory}>
<Fero/>
</Router>
);
}
}

export default App;

最佳答案

好吧,事实证明递归的解决方案是使用不同的 axios 实例进行 token 刷新,因此拦截器没有拦截过期刷新 token 的 HTTP 401 响应,这是完整的解决方案:

import React, { Component } from 'react';
import createHistory from 'history/createBrowserHistory';
import {Router} from 'react-router';

import Fero from './containers/Fero/Fero';
import {setTokens, getRefreshToken, getToken} from './utils/auth';

import axios from 'axios';

const myhistory = createHistory();
const refresh = axios.create();


axios.interceptors.response.use(function (response) {
return response;
}, function (error) {
const originalRequest = error.config;
if (error.response.status === 401 && Boolean(getRefreshToken())) {
// Hace la solicitud de refresco de tokens
return refresh.get('/api/v1/auth', {headers: {'Authorization': 'Bearer ' + getRefreshToken()}})
.then((responseData) => {
// actualiza la información de OAuth
setTokens(responseData.data.access_token, responseData.data.refresh_token);
axios.defaults.headers.common['Authorization'] = 'Bearer ' + getToken();
originalRequest.headers['Authorization'] = 'Bearer ' + getToken();
// re-intenta la solicitud original
return axios(originalRequest);
}).catch((error) => {
setTokens("", "");
myhistory.replace("/login");
});
}
return Promise.reject(error);
});

class App extends Component {
render() {
return (
<Router history={myhistory}>
<Fero/>
</Router>
);
}
}

export default App;

src/utils/auth.js的内容:

export const isAuth = () => {
return window.localStorage.getItem("token") && window.localStorage.getItem("refresh_token");
};

export const getToken = () => {
return isAuth() ? window.localStorage.getItem("token") : "";
};

export const getRefreshToken = () => {
return isAuth() ? window.localStorage.getItem("refresh_token") : "";
};

export const setTokens = (token, refresh) => {
window.localStorage.setItem("token", token);
window.localStorage.setItem("refresh_token", refresh);
};

关于javascript - 如果使用 axios 刷新 token 已过期,则正确重定向用户,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53737906/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com