IT TIP

모든 axios 요청에 대한 Authorization 헤더 첨부

itqueen 2020. 11. 22. 21:04
반응형

모든 axios 요청에 대한 Authorization 헤더 첨부


API 서버에서 토큰을 가져 오는 react / redux 애플리케이션이 있습니다. 사용자가 인증 된 후 모든 axios 요청이 작업의 모든 요청에 ​​수동으로 첨부 할 필요없이 해당 토큰을 Authorization 헤더로 갖도록 만들고 싶습니다. 나는 반응 / redux에 상당히 익숙하며 최선의 접근 방식을 확신하지 못하며 Google에서 품질 히트를 찾지 못했습니다.

내 redux 설정은 다음과 같습니다.

// 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;
  }
}

내 토큰은 아래의 redux 저장소에 저장됩니다 state.session.token.

진행하는 방법에 대해 조금 잃었습니다. 루트 디렉토리의 파일에 axios 인스턴스만들고 node_modules 대신 업데이트 / 가져 오기를 시도했지만 상태가 변경 될 때 헤더를 첨부하지 않습니다. 모든 피드백 / 아이디어는 대단히 감사합니다.


이를 달성하는 방법에는 여러 가지가 있습니다. 여기에서 가장 일반적인 두 가지 접근 방식을 설명했습니다.

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입니다.

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 / 쿠키에서 토큰을 검색 할 수도 있습니다.


"axios": "^ 0.17.1"버전을 사용하는 경우 다음과 같이 할 수 있습니다.

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();

행운을 빕니다.


마찬가지로 다음과 같은 호출에서 토큰을 설정하거나 삭제하는 함수가 있습니다.

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}`;
  }
}

초기화시 항상 기존 토큰을 정리 한 다음받은 토큰을 설정합니다.


나중에 다른 API 경로를 호출하고 토큰을 저장소에 보관하려면 redux 미들웨어 를 사용해보십시오 .

The middleware could listen for the an api action and dispatch api requests through axios accordingly.

Here is a very basic example:

actions/api.js

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'
  };
}

middleware/api.js

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);
};

Sometimes you get a case where some of the requests made with axios are pointed to endpoints that do not accept authorization headers. Thus, alternative way to set authorization header only on allowed domain is as in the example below. Place the following function in any file that gets executed each time React application runs such as in routes file.

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);
    });

}

참고URL : https://stackoverflow.com/questions/43051291/attach-authorization-header-for-all-axios-requests

반응형