使用axios Interceptors+React+Redux刷新代币



在我的应用程序中,我使用带有Redux和axios的React。

如果需要,我正在尝试通过axios拦截器刷新我的JWT令牌。

我可以拦截请求,检查我的访问令牌是否有效,如果它过期,我可以使用刷新令牌请求一对新的令牌。

然而,在我获得新的访问和刷新令牌后,我的应用程序不会继续原始请求,但它会停止并尝试呈现错误的组件(因为我缺少原始请求的响应(。

我相信在我管理异步功能的方式上有一些错误

我配置了一个axios实例如下

在axiosHelper.js 中

import axios from 'axios';
import jwt_decode from "jwt-decode"
import dayjs from 'dayjs'
let authTokens =  localStorage.getItem('authTokens') ? JSON.parse(localStorage.getItem('authTokens')) : null 
const instance = axios.create({ baseURL: 'http://localhost:8000'});
instance.interceptors.request.use(async (req) => {
if(!authTokens){
authTokens =  localStorage.getItem('authTokens') ? 
JSON.parse(localStorage.getItem('authTokens')) : null 
}
const user = jwt_decode(authTokens.access)
const isExpired = dayjs.unix(user.exp).diff(dayjs()) < 1
if (!isExpired) return req
const {tokens} = await axios.post(`/refresh-url/`, {
refresh: authTokens.refresh
})
console.log('refreshed1')
const data = authTokens
data.refresh = tokens.refresh
data.access = tokens.access
console.log('refreshed2')
localStorage.setItem('authTokens',JSON.stringify(data))
req.headers.Authorization = `Bearer ${tokens.access}`
console.log('refreshed3')
return req
}, error => {
return Promise.reject(error);
});

export default instance;

在我的操作中,我导入实例,如本例所示在操作中.js

import axios from '../axiosHelper.js '
...(here my imports and actions)...
const action = async () =>{
const config = { headers: {
'Content-type': 'application/json',
Authorization: `Bearer ${token.access}` // token from the redux store
}
const { data } = await axios.get(
`/api/my-url/`,
config
)
...(send data to reducer)...
}

然后在我的组件中,我通过useEffect中的dispatch调用我的操作。在Home.js 中

const Home = (props) => {
const dispatch = useDispatch()
useEffect(() =>{
dispatch(action())
}, [dispatch])
return (<my component/>)
}

我认为这个问题与调度有关。如果访问令牌有效,则一切正常。然而,如果它过期了,我的拦截器会发送刷新令牌的请求(这是成功的(,但一旦返回令牌,我的组件就会尝试渲染,axios拦截器中的其余代码就会被忽略(我用控制台日志检查了这一点…(,并且不会发送原始请求(我检查了它没有到达我的后端服务器(。

我真的很感激你的帮助,因为我不知道如何解决这个问题!

我通过将redux存储导入到我的axiosHelper.js脚本中,然后在我的axios拦截器中使用store.dispatch(refreshaction(authTokens.refresh))来解决这个问题。

最新更新