axios-auth-refresh 问题
Issue with axios-auth-refresh
我正在尝试通过 React 实现刷新令牌。我正在使用这个库 axios-auth-refresh,它似乎工作得很好,除了一个 API.
// api.js
import Axios from "axios";
import Cookies from 'js-cookie'
import { TOKEN_COOKIE_NAME, REFRESH_TOKEN_COOKIE_NAME } from '../constants/constants';
import createAuthRefreshInterceptor from 'axios-auth-refresh';
const api = Axios.create({
baseURL: process.env.REACT_APP_BACKEND_URL,
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
}
});
const refreshAuthLogic = async (failedRequest) => {
const refresh_token = Cookies.get(REFRESH_TOKEN_COOKIE_NAME);
// if(!refresh_token) return;
console.log(refresh_token);
const tokenRefreshResponse = await api.post('auth/createtoken', {
}, {
headers: {'Authorization': 'Bearer ' + refresh_token},
validateStatus: () => true
});
console.log(tokenRefreshResponse);
if(tokenRefreshResponse.data.statusCode === 401 || tokenRefreshResponse.data.statusCode === 403) {
Cookies.remove(REFRESH_TOKEN_COOKIE_NAME);
if(!window.location.href.includes('login')) {
window.location.href = "http://localhost:3000/login";
}
return;
}
const access_token = tokenRefreshResponse.data.access_token;
Cookies.set(TOKEN_COOKIE_NAME, access_token, { expires: 60 })
api.defaults.headers.Authorization = `Bearer ${access_token}`
failedRequest.response.config.headers['Authorization'] = 'Bearer ' + access_token;
}
// Instantiate the interceptor (you can chain it as it returns the axios instance)
createAuthRefreshInterceptor(api, refreshAuthLogic);
export default api;
如果返回 401,则以下 api 调用不会重复:
const fetchUsers = async () => {
const { data } = await api.get(`users/`, {params: {tripUsers: true}}, {
validateStatus: (status) => status !== 401 && status !== 403
})
setUsers(data);
}
useEffect(() => {
fetchUsers();
}, [])
如果返回 401,以下 api 调用会重复:
const fetchProfile = async () => {
const { data } = await api.get(`/users/${user.userId}`, {}, {
validateStatus: (status) => status !== 401 && status !== 403
})
const {statusCode, message} = data;
console.log(data);
if(!statusCode) {
console.log(data);
setState(data);
}
}
useEffect(() => {
fetchProfile();
}, [])
请帮忙。
在这个问题上花了一些时间后,我决定创建一个通用的 API 调用程序,而不是使用 axios 拦截器或任何其他库。这是我的通用 axios API 来电者。它仍然可以改进,但想法是如果第一个令牌已过期,则使用新令牌再次调用 API。
// api.js
import Axios from "axios";
import Cookies from 'js-cookie'
import { TOKEN_COOKIE_NAME, REFRESH_TOKEN_COOKIE_NAME } from '../constants/constants';
const api = Axios.create({
baseURL: process.env.REACT_APP_BACKEND_URL,
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
}
});
export const callApi = async (method, url, params, other) => {
const validateStatus =
url === 'auth/login' ? () => true : (status) => status !== 401 && status !== 403
const options = {
url,
method,
validateStatus,
...other
}
options[method === 'GET' ? 'params' : 'data'] = params;
console.log(options);
try {
const data = await api(options);
return Promise.resolve(data);
} catch (err) {
console.log(err.response.status);
if (err && err.response && err.response.status === 401) {
return performTokenRefresh(options);
} else {
return Promise.reject(err);
}
}
};
const performTokenRefresh = async (options) => {
const refresh_token = Cookies.get(REFRESH_TOKEN_COOKIE_NAME);
if(!refresh_token) return {};
const tokenRefreshResponse = await api.post('auth/createtoken', {
}, {
headers: {'Authorization': 'Bearer ' + refresh_token},
validateStatus: () => true
});
if(tokenRefreshResponse.data.statusCode === 401 || tokenRefreshResponse.data.statusCode === 403) {
Cookies.remove(REFRESH_TOKEN_COOKIE_NAME);
if(!window.location.href.includes('login')) {
window.location.href = "http://localhost:3000/login";
}
return {};
}
const access_token = tokenRefreshResponse.data.access_token;
Cookies.set(TOKEN_COOKIE_NAME, access_token, { expires: 60 })
api.defaults.headers.Authorization = `Bearer ${access_token}`
return api(options);
}
export default api;
我正在尝试通过 React 实现刷新令牌。我正在使用这个库 axios-auth-refresh,它似乎工作得很好,除了一个 API.
// api.js
import Axios from "axios";
import Cookies from 'js-cookie'
import { TOKEN_COOKIE_NAME, REFRESH_TOKEN_COOKIE_NAME } from '../constants/constants';
import createAuthRefreshInterceptor from 'axios-auth-refresh';
const api = Axios.create({
baseURL: process.env.REACT_APP_BACKEND_URL,
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
}
});
const refreshAuthLogic = async (failedRequest) => {
const refresh_token = Cookies.get(REFRESH_TOKEN_COOKIE_NAME);
// if(!refresh_token) return;
console.log(refresh_token);
const tokenRefreshResponse = await api.post('auth/createtoken', {
}, {
headers: {'Authorization': 'Bearer ' + refresh_token},
validateStatus: () => true
});
console.log(tokenRefreshResponse);
if(tokenRefreshResponse.data.statusCode === 401 || tokenRefreshResponse.data.statusCode === 403) {
Cookies.remove(REFRESH_TOKEN_COOKIE_NAME);
if(!window.location.href.includes('login')) {
window.location.href = "http://localhost:3000/login";
}
return;
}
const access_token = tokenRefreshResponse.data.access_token;
Cookies.set(TOKEN_COOKIE_NAME, access_token, { expires: 60 })
api.defaults.headers.Authorization = `Bearer ${access_token}`
failedRequest.response.config.headers['Authorization'] = 'Bearer ' + access_token;
}
// Instantiate the interceptor (you can chain it as it returns the axios instance)
createAuthRefreshInterceptor(api, refreshAuthLogic);
export default api;
如果返回 401,则以下 api 调用不会重复:
const fetchUsers = async () => {
const { data } = await api.get(`users/`, {params: {tripUsers: true}}, {
validateStatus: (status) => status !== 401 && status !== 403
})
setUsers(data);
}
useEffect(() => {
fetchUsers();
}, [])
如果返回 401,以下 api 调用会重复:
const fetchProfile = async () => {
const { data } = await api.get(`/users/${user.userId}`, {}, {
validateStatus: (status) => status !== 401 && status !== 403
})
const {statusCode, message} = data;
console.log(data);
if(!statusCode) {
console.log(data);
setState(data);
}
}
useEffect(() => {
fetchProfile();
}, [])
请帮忙。
在这个问题上花了一些时间后,我决定创建一个通用的 API 调用程序,而不是使用 axios 拦截器或任何其他库。这是我的通用 axios API 来电者。它仍然可以改进,但想法是如果第一个令牌已过期,则使用新令牌再次调用 API。
// api.js
import Axios from "axios";
import Cookies from 'js-cookie'
import { TOKEN_COOKIE_NAME, REFRESH_TOKEN_COOKIE_NAME } from '../constants/constants';
const api = Axios.create({
baseURL: process.env.REACT_APP_BACKEND_URL,
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
}
});
export const callApi = async (method, url, params, other) => {
const validateStatus =
url === 'auth/login' ? () => true : (status) => status !== 401 && status !== 403
const options = {
url,
method,
validateStatus,
...other
}
options[method === 'GET' ? 'params' : 'data'] = params;
console.log(options);
try {
const data = await api(options);
return Promise.resolve(data);
} catch (err) {
console.log(err.response.status);
if (err && err.response && err.response.status === 401) {
return performTokenRefresh(options);
} else {
return Promise.reject(err);
}
}
};
const performTokenRefresh = async (options) => {
const refresh_token = Cookies.get(REFRESH_TOKEN_COOKIE_NAME);
if(!refresh_token) return {};
const tokenRefreshResponse = await api.post('auth/createtoken', {
}, {
headers: {'Authorization': 'Bearer ' + refresh_token},
validateStatus: () => true
});
if(tokenRefreshResponse.data.statusCode === 401 || tokenRefreshResponse.data.statusCode === 403) {
Cookies.remove(REFRESH_TOKEN_COOKIE_NAME);
if(!window.location.href.includes('login')) {
window.location.href = "http://localhost:3000/login";
}
return {};
}
const access_token = tokenRefreshResponse.data.access_token;
Cookies.set(TOKEN_COOKIE_NAME, access_token, { expires: 60 })
api.defaults.headers.Authorization = `Bearer ${access_token}`
return api(options);
}
export default api;