当前位置: 首页 > 面试题库 >

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

阮才俊
2023-03-14
问题内容

我有一个文件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;


 类似资料:
  • 我正在为我的azure无状态服务fabric应用程序从密钥存储库中获取机密值,并在100s密钥存储库机密中仅有2个密钥存储库机密获得401个依赖项错误(如果我通过connected application insight检查的话)。下面给出的是通过应用程序洞察显示的依赖错误的截图,其中一个密钥存储库的秘密。 这里请求路径是https://mykeyvaultname.vault.azure.net

  • 问题内容: 我正在使用HP ALM版本12.55.113。我正在尝试通过REST- API自动上传测试结果。经过身份验证并尝试读取一个简单的缺陷后,我收到了401未经身份验证的错误。我使用以下示例代码检索有效的LWSSO和QCSession Cookie: 我得到以下控制台输出: 登录:InboundJaxrsResponse {context = ClientResponse {method =

  • 问题内容: 下面是我的AutoIt脚本(UI3_Authentication.au3),用于处理Windows身份验证弹出窗口。 以下是我对上述AutoIt exe文件的Selenium代码调用。 当我运行上述Selenium文件时,它将打开页面并弹出身份验证。但这不是在插入用户名和密码。它等待用户输入。 问题答案: 我解决了 其实这是我的坏事。以前,我的代码是这样的: 我在get()之前添加了a

  • 这是我使用的授权标头: 以下是我使用的基本字符串: 以下是我的推特文档: 步骤1:获取特殊请求令牌 首先,您使用应用程序的使用者密钥向Twitter请求令牌URLhttps://api.twitter.com/oauth/request_token发出HTTPS请求。除了传统的oauth_*签名参数之外,您还必须包含设置为reverse_auth值的x_auth_mode。 例如,考虑使用令牌秘密

  • 我已尝试在URL中发送用户名和密码 我已尝试使用报警处理,但不起作用。 我尝试了中提供的解决方案-如何使用Java处理Selenium WebDriver弹出的身份验证,几乎所有的解决方案都不是AutoIT,但没有一个对我有效 我有一个Maven项目,我正在尝试从project.properties文件发送带有用户名和密码的url,看起来像这样- URL=https://username:pass

  • 我使用的是在远程服务器上的脚本上运行curl的本地php脚本。远程脚本受http身份验证保护。 当我运行本地脚本时,我收到以下错误: “此服务器无法验证您是否有权访问URL”/script.php”。您提供了错误的凭据(例如,密码错误),或者您的浏览器不知道如何提供所需的凭据。 如果您被允许请求文档,请检查您的用户ID和密码,然后重试。 如果您认为这是服务器错误,请联系网站管理员。 错误401“