所以我有一个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
}
现在我要导出该实例以在其他文件中使用
答案 0 :(得分:2)
您可以使用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);
}
答案 1 :(得分:2)
With Axios you have the ability to set default values for all requests.
因此,对于单个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 also provides and extremely helpful function called interceptors,可用于在发出请求之前检查该请求。您可以用来检查以确保请求具有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标头的存在,还要检查配置中的新授权值。您想检查该配置值,因为我们将把它用作标志以让拦截器知道它是否应该跳过请求。如果不这样做,授权请求将触发另一个授权请求并无限循环。