401(Authentication Error)을 액시스로 처리하여 어떻게 대응합니까?
axios ajax 요청에 대한 래퍼가 포함된 request.js 파일이 하나 있습니다.여러 리액트 컴포넌트에서 요청 함수를 호출하고 있으며 요청 중 하나가 실패하면 토큰을 새로 고치고 실패한 모든 요청을 다시 시도합니다.인터셉터를 사용할 수는 있지만 어떻게 구현해야 할지 모르겠어요.제발 도와주세요.
request.request.discloss를 실행합니다.
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;
401 오류를 처리하기 위해 가로채기를 사용하는 경우 코드 스니펫이 있습니다.
axios.interceptors.response.use(response => {
return response;
}, error => {
if (error.response.status === 401) {
//place your reentry code
}
return error;
});
이 방법은 다음과 같습니다.
// Add a 401 response interceptor
window.axios.interceptors.response.use(function (response) {
return response;
}, function (error) {
if (401 === error.response.status) {
// handle error: inform user, go to login, etc
} else {
return Promise.reject(error);
}
});
출처: https://gist.github.com/yajra/5f5551649b20c8f668aec48549ef5c1f
난 또 다른 문제가 있었어:
응답이 없는 "네트워크 오류"
tl;dr - CORS와 설정 방법에 문제가 있어 악시스는 브라우저로부터 정보를 얻을 수 없었습니다.서버측에서 분류해야 합니다.
묘사
유사한 문제가 있는 경우 브라우저 콘솔에 표시됩니다.브라우저는 Ajax를 통해 다른 URL에 액세스할 수 없도록 합니다.
제 경우(node.js - express)는 필터 순서입니다.이 특정 요구에 대한 핸들러 뒤에 CORS 필터(dev 환경)가 추가되어 서버가 적절한 CORS 헤더를 송신하고 있지 않았기 때문에 브라우저는 요구를 실행할 수조차 없었습니다(서버에 대한 호출은 전혀 없었습니다).에러 오브젝트가 반환되지 않았습니다).
다음 코드로 작업했습니다.
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년입니다만, 또 다른 실장입니다.위의 솔루션은 훌륭하지만 여러 번 실패한 요청에서는 제대로 작동하지 않습니다.그 결과 콜은업데이트된 토큰이 포함된 토큰도 있습니다.
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;
이 방법으로 공리 401을 잡을 수 있습니다.
axios.post('/add')
.then(function (response) {...})
.catch(function (error) {
console.log(error.response.status) // 401
console.log(error.response.data.error) //Please Authenticate or whatever returned from server
if(error.response.status==401){
//redirect to login
}
})
몇 가지 다른 질문을 드렸는데, 여기 제 코드가 있습니다.
import axios from 'axios';
const instance = axios.create({
baseURL: window.location.hostname === 'localhost' ? 'http://localhost:5001/api/v1' : 'https://api.mysite.com/api/v1'
});
instance.defaults.headers.common['Content-Type'] = 'multipart/form-data';
//validate response
instance.interceptors.response.use((response) => {
return response;
}, (error) => {
if (error.response.status === 401) {
return window.location.href = '/login'
}
return Promise.reject(error);
});
// Set the AUTH token for any request
instance.interceptors.request.use(
(config) => {
const token = localStorage.getItem('token');
config.headers.Authorization = token ? `Bearer ${token}` : '';
return config;
}
)
export default instance;
모듈에서 Axios를 사용할 때 명확한 답을 찾을 수 없었습니다.인터셉터를 사용하고 있는 악리의 인스턴스에 추가해야 합니다.
api.module
import axios from 'axios'
import store from '../state'
//Defaults will be combined with the instance
axios.defaults.baseURL = '/some/page.aspx';
//Create Axios Instance
const axiosInstance = axios.create({
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json; charset=UTF-8'
}
});
//Add interceptors to instance
axiosInstance.interceptors.response.use(
response => response,
error => {
if (!error.response) {
store.commit('setServiceAvailable', false);
}
else if (error.response.status === 401) {
store.commit('setUserAuthorised', false);
}
return error;
});
export default axiosInstance;
그런 다음 정상적으로 사용
component.displaces(컴포넌트).
import api from '../api'
...
async getServersJson() {
try {
var response = await api.post('GetReportAsServers', {name: 'get-servers', args: null});
this.serversJson = this.prettifyJson(response.data.d);
}
catch (error) {
console.error(`Exception getting servers. ${error}`);
}
},
언급URL : https://stackoverflow.com/questions/47216452/how-to-handle-401-authentication-error-in-axios-and-react
'programing' 카테고리의 다른 글
Django 앱의 Access-Control-Allow-Origin (0) | 2023.04.01 |
---|---|
로컬에서 값을 읽습니다.vs 2017 Azure Function 개발에서 settings.json을 소개합니다. (0) | 2023.04.01 |
AngularJS용 커스텀 모듈은 어떻게 작성합니까? (0) | 2023.04.01 |
ie9+에서 약속을 이행하는 방법이 있는가? (0) | 2023.04.01 |
AngularJS에서 디렉티브를 동적으로 추가하려면 어떻게 해야 합니까? (0) | 2023.04.01 |