如何处理axios中的401(身份验证错误)并做出反应?

我有一个文件request.js,其中包含axios

ajax请求的包装。我正在从多个React组件中调用请求函数,当请求之一失败时,我想刷新令牌并再次重试所有失败的请求。我可以使用拦截器,但是我不知道如何实现它。请帮忙。

request.js

 var client = axios.create({

baseURL: 'http://192.168.1.3:3000',

headers: {

appID: 8,

version: "1.1.0",

empID: localStorage.getItem('empID'),

token: localStorage.getItem('accessToken')

}

});

const request = function(options) {

const onSuccess = function(response) {

console.debug('Request Successful!', response);

return response.data;

}

const onError = function(error) {

console.error('Request Failed:', error.config);

if (error.response) {

console.error('Status:', error.response.status);

console.error('Data:', error.response.data);

console.error('Headers:', error.response.headers);

} else {

console.error('Error Message:', error.message);

}

return Promise.reject(error.response || error.message);

}

return client(options)

.then(onSuccess)

.catch(onError);

options

}

export default request;

回答:

我用以下代码工作

import axios from 'axios';

import config from '../../configuration.json';

import qs from 'qs';

const baseURL = config['baseUrl_local'];

let authTokenRequest;

/**

* @description axios instance for ajax requests

*/

var client = axios.create({

baseURL: baseURL,

headers: {

appID: 8,

version: "1.1.0",

empID: localStorage.getItem('empID'),

token: localStorage.getItem('accessToken')

}

});

/**

* @description this method calls a requestNewToken method to issue a

new token to the client

*/

function getAuthToken() {

if (!authTokenRequest) {

authTokenRequest = requestNewToken();

authTokenRequest.then(resetAuthTokenRequest, resetAuthTokenRequest);

}

return authTokenRequest;

}

/**

* @description this method requests the server to issue a new token,

the server response is updated in local storage accessToken

*/

function requestNewToken() {

var newToken = request({

method: "post",

url: '/sign-in',

data: qs.stringify({

"userName":localStorage.getItem('userName'),

"password":localStorage.getItem('password')

})

}).then((res)=>{

if(res.status == "success"){

localStorage.setItem('accessToken',res.data.accessToken);

//if featureArray is present in response object, update the

featureArray in local storage

if(res.data.features){

localStorage.setItem(

'featureArray',

JSON.stringify(res.data.features));

}

client = axios.create({

baseURL: baseURL,

headers: {

appID: 8,

version: "1.1.0",

empID: localStorage.getItem('empID'),

token: localStorage.getItem('accessToken')

}

});

} else {

window.location = "/logout";

}

});

return newToken;

}

function resetAuthTokenRequest() {

authTokenRequest = null;

}

/**

* @description if any of the API gets 401 status code, this method

calls getAuthToken method to renew accessToken

* updates the error configuration and retries all failed requests

again

*/

client.interceptors.response.use(undefined, err => {

const error = err.response;

// if error is 401

if (error.status===401 && error.config &&

!error.config.__isRetryRequest) {

// request for a new token

return getAuthToken().then(response => {

// update the error config with new token

error.config.__isRetryRequest = true;

error.config.headers.token= localStorage.getItem("accessToken");

return client(error.config);

});

}

});

/**

* @description wrapper for making ajax requests

* @param {object} object with method,url,data etc.

*/

const request = function(options) {

const onSuccess = function(response) {

return response.data;

}

const onError = function(error) {

//console.error('Request Failed:', error.config);

if (error.response) {

//console.error('Status:', error.response.status);

//console.error('Data:', error.response.data);

//console.error('Headers:', error.response.headers);

} else {

console.error('Error Message:', error.message);

}

return Promise.reject(error.response || error.message);

}

return client(options)

.then(onSuccess)

.catch(onError);

options

}

export default request;

[编辑]它的2019,这是相同的另一个实现。上面的解决方案很棒,但是不能用于多个失败的请求,反过来,它也会调用带有更新令牌的getToken。

 import axios from "axios";

/* @internal */

import config from "../config";

import TokenService from "./token_service";

class Request {

constructor() {

this.baseURL = config.baseUrl;

this.isRefreshing = false;

this.failedRequests = [];

this.tokenService = new TokenService();

this.client = axios.create({

baseURL: config.apiServerBaseUrl,

headers: {

clientSecret: this.clientSecret,

},

});

this.beforeRequest = this.beforeRequest.bind(this);

this.onRequestFailure = this.onRequestFailure.bind(this);

this.processQueue = this.processQueue.bind(this);

this.client.interceptors.request.use(this.beforeRequest);

this.client.interceptors.response.use(this.onRequestSuccess,

this.onRequestFailure);

}

beforeRequest(request) {

const token = TokenService.getAccessToken();

request.headers.Authorization = `Token ${token}`;

return request;

}

static onRequestSuccess(response) {

return response.data;

}

async onRequestFailure(err) {

const { response } = err;

if (response.status === 401 && err && err.config && !err.config.__isRetryRequest) {

if (this.isRefreshing) {

try {

const token = await new Promise((resolve, reject) => {

this.failedRequests.push({ resolve, reject });

});

err.config.headers.Authorization = `Bearer ${token}`;

return this.client(err.config);

}

catch (e) {

return e;

}

}

this.isRefreshing = true;

err.config.__isRetryRequest = true;

return new Promise((resolve, reject) => {

this.tokenService.refreshAccessToken().then((token) => {

this.tokenService.setAccessToken(token);

err.config.headers.Authorization = `Bearer ${token}`;

this.isRefreshing = false;

this.processQueue(null, token);

resolve(this.client(err.config));

}).catch((e) => {

this.processQueue(e, null);

reject(err.response);

});

});

}

throw response;

}

processQueue(error, token = null) {

this.failedRequests.forEach((prom) => {

if (error) {

prom.reject(error);

} else {

prom.resolve(token);

}

});

this.failedRequests = [];

}

}

const request = new Request();

export default request.client;

以上是 如何处理axios中的401(身份验证错误)并做出反应? 的全部内容, 来源链接: utcz.com/qa/435833.html

回到顶部