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