Joindre l'en-tête D'autorisation pour toutes les requêtes axios

j'ai une application react/redux qui récupère un token depuis un serveur api. Après l'authentification de l'utilisateur, j'aimerais faire en sorte que toutes les requêtes axios aient ce token comme en-tête D'autorisation sans avoir à le fixer manuellement à chaque requête de l'action. Je suis assez nouveau pour réagir / redux et ne suis pas sûr de la meilleure approche et ne trouve pas de résultats de qualité sur google.

voici ma configuration de 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;
  }
}

mon token est stocké dans redux store sous state.session.token.

je suis un peu perdu sur la façon de procéder. J'ai essayé de faire un axios exemple dans un fichier de mon répertoire racine et mettre à jour/importer cela au lieu de node_modules mais il n'est pas attacher l'en-tête quand l'état change. Tout commentaire / idées sont très appréciés, merci.

18
demandé sur awwester 2017-03-27 19:05:05

6 réponses

documentationaxios vous pouvez voir qu'il y a un mécanisme disponible qui vous permet de définir l'en-tête par défaut qui sera envoyé avec chaque requête que vous faites.

axios.defaults.headers.common['Authorization'] = AUTH_TOKEN;

alors dans votre cas:

axios.defaults.headers.common['Authorization'] = store.getState().session.token;

si vous voulez, vous pouvez créer une fonction auto-exécutable qui définira elle-même l'en-tête d'autorisation lorsque le token est présent dans le magasin.

(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'];
         */
     }
})();

Maintenant vous n'avez plus besoin d'attacher manuellement un token à chaque requête. Vous pouvez placer la fonction ci-dessus dans le fichier qui est garanti pour être exécuté à chaque fois (e.g: fichier qui contient les routes).

Espérons que cela aide :)

16
répondu Hardik Modha 2018-07-02 07:04:31

la meilleure solution pour moi est de créer un service client que vous instanciez avec votre token et l'utiliser pour envelopper 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);

dans ce client, vous pouvez également récupérer le token à partir du cookie / localStorage, comme vous le souhaitez.

19
répondu Kmaschta 2017-10-18 06:55:48

Si vous utilisez "axios": "^0.17.1" version, vous pouvez faire comme ceci:

Créer une instance de l'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;
  });

alors pour toute requête le token sera sélectionné dans localStorage et ajouté aux en-têtes de requête.

j'utilise la même instance dans toute l'application avec ce code:

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

Bonne chance.

10
répondu llioor 2017-12-17 01:52:37

de même, nous avons une fonction pour définir ou supprimer le token des appels comme ceci:

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

nous nettoyons toujours le jeton existant à l'initialisation, puis nous établissons le jeton reçu.

2
répondu elQueFaltaba 2017-06-28 08:58:11

si vous voulez appeler d'autres routes api dans le futur et garder votre token dans le magasin alors essayez à l'aide de redux middleware.

l'middleware peut écouter l'action d'une api et envoyer les requêtes api via axios en conséquence.

Voici un exemple très simple:

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);
};
1
répondu Paul. B 2017-11-20 10:05:13

Il y a parfois un cas où certaines des requêtes faites avec axios sont pointées vers des points terminaux qui n'acceptent pas les en-têtes d'autorisation. Ainsi, une autre façon de définir l'en-tête d'autorisation seulement sur le domaine autorisé est comme dans l'exemple ci-dessous. Placez la fonction suivante dans n'importe quel fichier qui est exécuté chaque fois que L'application React exécute tel que dans le fichier des routes.

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

}
0
répondu Karolis Ramanauskas 2018-03-28 09:06:54