Javascript 请求前异步身份验证

Javascript 请求前异步身份验证,javascript,asynchronous,axios,Javascript,Asynchronous,Axios,因此,我有一个API,我正试图通过使用凭证点击端点进行身份验证。这部分我已经开始工作,然后保存收到的令牌,并在所有后续请求中使用它 我的问题是authenticate方法是异步的,但所有其他请求方法(如get)都需要来自authenticate方法的令牌。所以我不能只导出我的get方法,因为导出是同步的,正如我读到的,它将在身份验证发生之前导出。我可以对每个请求进行身份验证,但这似乎是浪费和低效的 我不知道该怎么做,我正在使用axios,正确的方法是什么 编辑 我在这里会更具体一点。我已经创建了

因此,我有一个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
}
现在我想导出该实例,以便在其他文件中使用

您可以使用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:

因此,对于单个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*作为“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-token头是否存在,还要检查配置中是否存在新的授权值。您需要检查该配置值,因为我们将使用它作为一个标志,让拦截器知道它是否应该跳过一个请求。如果您不这样做,授权请求将触发另一个授权请求和无限循环。

如果您有ES6,您可以等待它。你能给我举个例子吗?伪代码很可靠。const token=wait authenticate const res=getendpoint,token@ruby_newbie await是在ECMAScript 2017中引入的,而不是在ECMAScript 2015(也称为ES6Ok)中引入的,但该模型是基于每个请求的。我想保存该令牌,将其包含在axios实例头中,然后能够使用该实例发出请求,而不必每次都手动包含该头。一种方法是使用authenticate。然后在第一次请求时链,或者如果令牌不存在,如果后续请求中存在令牌,则跳过它。因此,对于每个API调用,我都需要有一个内置条件来检查在发出请求之前是否设置了令牌?难道没有办法设置令牌一次,将其分配给axios实例,然后将该实例导入任何需要它进行API调用的文件中吗?您可以,但您需要确保在第一次调用获取之前发生。哈哈,是的!这正是我想做的,我只是不知道怎么做!对于迟来的回复表示歉意,并感谢您的回复。我知道这是多么有价值,但我仍然不知道如何同步运行此身份验证步骤,以便在进行任何其他api调用之前在标头中设置令牌。也许我只是个白痴,但如果你能举个例子的话,我会帮上大忙的。好吧,我知道你想做什么了,我更新了我的答案来提供逻辑!
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;
});