Я написал следующий код для Node.js для подключения к API моей CMS.API должен войти в систему один раз с именем пользователя и паролем, а затем приступить к выполнению запросов с токеном доступа.Однако токен доступа имеет ограниченное время, в течение которого он действителен - после этого API должен снова войти в систему и получить новый токен.
Когда я выполняю запросы к API, я всегда пытаюсь использовать текущий токен- если он больше не действителен, я получу 403 и инициирую новый вход в систему, после чего начальный запрос будет выполнен снова.
Проблема здесь в том, если несколько запросов одновременно пытаются получить доступ кAPI, все они инициируют вход в систему - что приводит к нескольким сеансам API в CMS, что плохо.Я думал, что этот случай был обработан с помощью Promises, но, видимо, мой код не работает так, как я себе представлял.
var api = {
url: 'servername',
user: 'user',
password: 'password',
token: null
};
var login_in_progress = true;
var loginPromise;
function loginApi() {
login_in_progress = true;
return new Promise(function (resolve, reject) {
request({
uri: api.url + api.user + ',' + api.password,
method: 'GET',
json: true
}, function (err, res, data) {
if (!err && res.statusCode === 200) {
api.token = data.token;
login_in_progress = false;
resolve(data);
} else {
login_in_progress = false;
reject(err);
}
});
});
}
var getContent = function (query) {
// Currently a login is running - wait till it's finished and then execute get
// at least that was the idea - but does not seem to work
if (login_in_progress && loginPromise) {
return new Promise(function (resolve, reject) {
loginPromise
.then(function () {
getContent(query)
.then(function (data) {
resolve(data);
})
.catch(function (err) {
reject(err);
});
})
.catch(function (err) {
reject(err);
});
});
} else {
// Do the actual request
// case 403 Api is logged out => reLogin
loginPromise = loginApi();
loginPromise
.then(function () {
getContent(query)
.then(function (data) {
resolve(data);
})
.catch(function (err) {
reject(err);
});
})
.catch(function (err) {
reject(err)
});
}
}
Очевидно, проверка того, что вход в систему в данный момент не выполняется, не происходит, и функция getContent всегданаталкивается на утверждение else.Я даже не уверен, сработает ли моя идея проверить работающий запрос на вход в систему.