모든 Axios 요청에 대한 Authorization 헤더 첨부
api 서버에서 토큰을 가져오는 react/redux 응용 프로그램이 있습니다.사용자가 인증한 후 액션의 모든 요청에 수동으로 연결하지 않고 모든 Axios 요청에 해당 토큰을 Authorization 헤더로 지정하려고 합니다.저는 리액션/리덕스를 처음 접하는 사람이라 최선의 접근법에 대해 확신이 없고 구글에서 질 높은 히트를 찾을 수 없습니다.
레독스 설정은 다음과 같습니다.
// actions.js
import axios from 'axios';
export function loginUser(props) {
const url = `https://api.mydomain.com/login/`;
const { email, password } = props;
const request = axios.post(url, { email, password });
return {
type: LOGIN_USER,
payload: request
};
}
export function fetchPages() {
/* here is where I'd like the header to be attached automatically if the user
has logged in */
const request = axios.get(PAGES_URL);
return {
type: FETCH_PAGES,
payload: request
};
}
// reducers.js
const initialState = {
isAuthenticated: false,
token: null
};
export default (state = initialState, action) => {
switch(action.type) {
case LOGIN_USER:
// here is where I believe I should be attaching the header to all axios requests.
return {
token: action.payload.data.key,
isAuthenticated: true
};
case LOGOUT_USER:
// i would remove the header from all axios requests here.
return initialState;
default:
return state;
}
}
내 토큰은 아래 레독스 스토어에 저장됩니다.state.session.token
.
어떻게 해야 할지 모르겠어요.루트 디렉토리에 있는 파일에 axios 인스턴스를 만들어 node_modules 대신 업데이트/import를 시도했지만 상태가 바뀌어도 헤더가 연결되지 않습니다.피드백/아이디어에 감사드립니다.
이를 실현하는 방법은 여러 가지가 있습니다.여기에서는 가장 일반적인 두 가지 접근법에 대해 설명했습니다.
1. Axios 대행 수신기를 사용하여 요청을 대행 수신하고 인증 헤더를 추가할 수 있습니다.
// Add a request interceptor
axios.interceptors.request.use(function (config) {
const token = store.getState().session.token;
config.headers.Authorization = token;
return config;
});
(2) 다음 문서로부터axios
디폴트 헤더를 설정할 수 있는 메커니즘이 있는 것을 알 수 있습니다.이것에 의해, 모든 요구에 대해서 송신됩니다.
axios.defaults.headers.common['Authorization'] = AUTH_TOKEN;
고객님의 경우:
axios.defaults.headers.common['Authorization'] = store.getState().session.token;
원하는 경우 토큰이 저장소에 있을 때 인증 헤더 자체를 설정하는 자체 실행 함수를 만들 수 있습니다.
(function() {
String token = store.getState().session.token;
if (token) {
axios.defaults.headers.common['Authorization'] = token;
} else {
axios.defaults.headers.common['Authorization'] = null;
/*if setting null does not remove `Authorization` header then try
delete axios.defaults.headers.common['Authorization'];
*/
}
})();
이제 모든 요청에 토큰을 수동으로 첨부할 필요가 없습니다.위의 함수를 매번 실행이 보증되는 파일(예: 경로를 포함하는 파일)에 배치할 수 있습니다.
Axios 인스턴스 만들기:
// Default config options
const defaultOptions = {
baseURL: <CHANGE-TO-URL>,
headers: {
'Content-Type': 'application/json',
},
};
// Create instance
let instance = axios.create(defaultOptions);
// Set the AUTH token for any request
instance.interceptors.request.use(function (config) {
const token = localStorage.getItem('token');
config.headers.Authorization = token ? `Bearer ${token}` : '';
return config;
});
그런 다음 모든 요청에 대해 localStorage에서 토큰이 선택되고 요청 헤더에 추가됩니다.
앱 전체에서 다음 코드로 동일한 인스턴스를 사용하고 있습니다.
import axios from 'axios';
const fetchClient = () => {
const defaultOptions = {
baseURL: process.env.REACT_APP_API_PATH,
method: 'get',
headers: {
'Content-Type': 'application/json',
},
};
// Create instance
let instance = axios.create(defaultOptions);
// Set the AUTH token for any request
instance.interceptors.request.use(function (config) {
const token = localStorage.getItem('token');
config.headers.Authorization = token ? `Bearer ${token}` : '';
return config;
});
return instance;
};
export default fetchClient();
나에게 가장 좋은 해결책은 토큰으로 인스턴스화할 클라이언트 서비스를 만들고 이를 사용하여 포장하는 것입니다.axios
.
import axios from 'axios';
const client = (token = null) => {
const defaultOptions = {
headers: {
Authorization: token ? `Token ${token}` : '',
},
};
return {
get: (url, options = {}) => axios.get(url, { ...defaultOptions, ...options }),
post: (url, data, options = {}) => axios.post(url, data, { ...defaultOptions, ...options }),
put: (url, data, options = {}) => axios.put(url, data, { ...defaultOptions, ...options }),
delete: (url, options = {}) => axios.delete(url, { ...defaultOptions, ...options }),
};
};
const request = client('MY SECRET TOKEN');
request.get(PAGES_URL);
이 클라이언트에서는 필요에 따라 localStorage/cookie에서 토큰을 검색할 수도 있습니다.
마찬가지로 다음과 같은 콜에서 토큰을 설정 또는 삭제하는 기능이 있습니다.
import axios from 'axios';
export default function setAuthToken(token) {
axios.defaults.headers.common['Authorization'] = '';
delete axios.defaults.headers.common['Authorization'];
if (token) {
axios.defaults.headers.common['Authorization'] = `${token}`;
}
}
초기화 시 항상 기존 토큰을 클리어하고 수신한 토큰을 확립합니다.
요점은 각 요구에 대해 인터셉터에 토큰을 설정하는 것입니다.
import axios from "axios";
const httpClient = axios.create({
baseURL: "http://youradress",
// baseURL: process.env.APP_API_BASE_URL,
});
httpClient.interceptors.request.use(function (config) {
const token = localStorage.getItem('token');
config.headers.Authorization = token ? `Bearer ${token}` : '';
return config;
});
향후 다른 API 루트를 호출하여 토큰을 스토어에 보관하고 싶다면 redux 미들웨어를 사용해 보십시오.
미들웨어는 api 액션을 리슨하고 그에 따라 api 요구를 acios를 통해 디스패치할 수 있습니다.
다음으로 매우 기본적인 예를 제시하겠습니다.
actions/api.syslog
export const CALL_API = 'CALL_API';
function onSuccess(payload) {
return {
type: 'SUCCESS',
payload
};
}
function onError(payload) {
return {
type: 'ERROR',
payload,
error: true
};
}
export function apiLogin(credentials) {
return {
onSuccess,
onError,
type: CALL_API,
params: { ...credentials },
method: 'post',
url: 'login'
};
}
미들웨어/api.module
import axios from 'axios';
import { CALL_API } from '../actions/api';
export default ({ getState, dispatch }) => next => async action => {
// Ignore anything that's not calling the api
if (action.type !== CALL_API) {
return next(action);
}
// Grab the token from state
const { token } = getState().session;
// Format the request and attach the token.
const { method, onSuccess, onError, params, url } = action;
const defaultOptions = {
headers: {
Authorization: token ? `Token ${token}` : '',
}
};
const options = {
...defaultOptions,
...params
};
try {
const response = await axios[method](url, options);
dispatch(onSuccess(response.data));
} catch (error) {
dispatch(onError(error.data));
}
return next(action);
};
경우에 따라서는 악리로 이루어진 요청 중 일부가 인가 헤더를 받지 않는 엔드포인트를 가리킬 수 있습니다.따라서 허가 도메인에만 인가 헤더를 설정하는 대체 방법은 다음과 같습니다.routes file과 같이 React 응용 프로그램이 실행될 때마다 실행되는 파일에 다음 함수를 배치합니다.
export default () => {
axios.interceptors.request.use(function (requestConfig) {
if (requestConfig.url.indexOf(<ALLOWED_DOMAIN>) > -1) {
const token = localStorage.token;
requestConfig.headers['Authorization'] = `Bearer ${token}`;
}
return requestConfig;
}, function (error) {
return Promise.reject(error);
});
}
아래처럼 새로운 인스턴스를 만들어 보세요.
var common_axios = axios.create({
baseURL: 'https://sample.com'
});
// Set default headers to common_axios ( as Instance )
common_axios.defaults.headers.common['Authorization'] = AUTH_TOKEN;
// Check your Header
console.log(common_axios.defaults.headers);
사용방법
common_axios.get(url).......
common_axios.post(url).......
export const authHandler = (config) => {
const authRegex = /^\/apiregex/;
if (!authRegex.test(config.url)) {
return store.fetchToken().then((token) => {
Object.assign(config.headers.common, { Authorization: `Bearer ${token}` });
return Promise.resolve(config);
});
}
return Promise.resolve(config);
};
axios.interceptors.request.use(authHandler);
비슷한 것을 실장하려고 할 때, 몇 가지 곤란한 상황에 부딪혔고, 이 대답에 근거해 생각해 낸 것이 이것입니다.제가 겪고 있는 문제는 다음과 같습니다.
- 저장소에서 토큰을 가져오는 요청에 액시오스를 사용하는 경우 헤더를 추가하기 전에 경로를 감지해야 합니다.그렇지 않으면 해당 콜에도 헤더가 추가되어 순환 경로 문제가 발생합니다.다른 콜을 검출하기 위해 regex를 추가하는 반대의 경우도 기능합니다.
- 스토어가 약속을 반환하는 경우 authHandler 함수의 약속을 해결하려면 콜을 스토어에 반환해야 합니다.비동기/Awit 기능을 사용하면 보다 쉽게/명확해질 수 있습니다.
- 인증 토큰 콜이 실패하거나 토큰을 취득하기 위한 콜인 경우에도 Configuration과의 약속을 해결해야 합니다.
언급URL : https://stackoverflow.com/questions/43051291/attach-authorization-header-for-all-axios-requests
'programing' 카테고리의 다른 글
'../build/Release/bson' 모듈을 찾을 수 없습니다. 코드: 'MODULE_NOT_FOUND' } js-bson:순수 JS 버전을 사용하여 c++ bson 확장을 로드하지 못했습니다. (0) | 2023.04.02 |
---|---|
Angular 1.5, 부모 컨트롤러에서 컴포넌트의 함수를 호출합니다. (0) | 2023.04.02 |
angularjs 앱에서 안전한(!) 인증 시스템을 얻는 방법 (0) | 2023.04.02 |
여러 JSON 개체를 가진 JSON 파일 로드 및 구문 분석 (0) | 2023.04.02 |
스프링 부트: 여러 SLF4J 바인딩 (0) | 2023.04.02 |