Асинхронная аутентификация перед запросом - PullRequest
0 голосов
/ 15 ноября 2018

Итак, у меня есть API, и я пытаюсь аутентифицироваться, ударяя по конечной точке с учетными данными (эту часть я получил, работая), а затем сохраняю полученный токен и использую его во всех последующих запросах.

Моя проблема в том, что метод authenticate() является асинхронным, но все другие методы запроса, такие как get(), требуют токен из метода authenticate(). Поэтому я не могу просто экспортировать мой get() метод, потому что экспорт синхронный (как я прочитал), и он будет экспортирован до того, как произойдет аутентификация. Я мог бы подтвердить подлинность для каждого запроса, но это кажется расточительным и неэффективным.

Я не уверен, что здесь делать, я использую axios, как правильно это сделать?

Редактировать

Я буду здесь более конкретным. Я создал экземпляр axios:

var instance = axios.create({
  baseURL: `http://${config.server}:${config.port}`,
  timeout: 1000,
  headers: {
    'Content-Type': 'application/json',
    'Accept': 'application/json'
  }
})

Я хочу получить токен аутентификации и включить его в заголовок экземпляра:

async function authenticate(instance) {
  const result = await instance.post(
    '/session',
    {
      'username': config.username,
      'password': config.password
    }
  )
  instance['X-Token'] = result.data.token
}

Теперь я хочу экспортировать этот экземпляр для использования в других файлах

Ответы [ 2 ]

0 голосов
/ 15 ноября 2018

С Axios у вас есть возможность установить значения по умолчанию для всех запросов.

Так что для одного экземпляра Axios вы можете сделать ...

async function authenticate(instance) {
  const result = await instance.post(
    '/session',
    {
      'username': config.username,
      'password': config.password
    }
  )
  instance.defaults.headers.common['X-Token'] = result.data.token;
}

В качестве альтернативы (что звучит так, как вы хотите), вы можете добавить его для экспорта Axios по умолчанию.Тогда все запросы будут автоматически иметь заголовок.

async function authenticate(endpoint, username, password) {
  const res = await axios.post(`${endpoint}/session`, { username, password });
  axios.defaults.headers.common['X-Token'] = result.data.token; 
}

Тогда вам не нужно беспокоиться о передаче экземпляра между всеми частями вашего приложения, вы можете просто использовать import * as axios from 'axios' и установить заголовок.


Axios также предоставляет и чрезвычайно полезную функцию, называемую перехватчиками , которую вы можете использовать для проверки запроса перед его выполнением.Вы можете использовать для проверки, чтобы убедиться, что запрос имеет заголовок auth, а если нет, вы можете выполнить эту логику.Я придумал это, и это, кажется, работает хорошо!

axios.interceptors.request.use(async (config) => {
  // request intercepted, check (1) the header is missing and (2) that the intercepted request isn't authorizing
  if (!config.headers.common['X-Token'] && config.authorizing !== true) {
    const { endpoint, username, password } = appConfig;

    // make a request to get your token AND pass our custom config
    const result = await axios.post(`${endpoint}/session`, { username, password }, { authorizing: true });

    // update axios to include the header for future requests
    axios.defaults.headers.common['X-Token'] = result.data.token;
  }
  return config;
});

Две вещи, которые вы хотите отметить - я не только проверяю наличие вашего заголовка X-токена, но и проверяюновое значение авторизации в конфиге.Вы хотите проверить это значение конфигурации, потому что мы собираемся использовать его в качестве флага, чтобы сообщить перехватчику, следует ли ему пропустить запрос.Если вы этого не сделаете, запрос авторизации вызовет другой запрос авторизации и бесконечный цикл.

0 голосов
/ 15 ноября 2018

Вы можете использовать async/await.Это полупсевдокод:

async function doStuff() {
  const result = await axios.authenticate();
  const token = // extract token from whatever format of result is
  const data = await axios.get(/* supply token to get */); 
}

Кроме того, вы можете просто использовать then:

function doStuff(token) {
  const token = // extract token from whatever format of result is
  const data = await axios.get(/* supply token to get */); 
}

axios.authenticate().then(result => {
  const token = // extract token from whatever format of result is
  doStuff(token);
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...