В моей базе данных каждый пользователь имеет некоторые учетные данные OAuth для третьей стороны, например:
{
acces_token: "",
expires_at: "",
refresh_token: ""
}
Когда нам нужен доступ к третьей стороне, если срок действия токена истек, мы обновляем его, что приводит к новым access_token
и refresh_token
.
Если для одного и того же пользователя одновременно запущены несколько функций firebase и срок действия маркера доступа истек, каждая функция пытается обновить токен.
- Первая запущенная функция - успешно и обновляет токены.
- Любая другая функция - не выполняется, поскольку она пытается обновить токен недействительными учетными данными (старыми учетными данными).
Есть ли способ заблокировать объект пользователя в базе данных (как в user/{userKey}
) и не разрешать чтение до тех пор, пока токен не будет обновлен в случае необходимости?
Редактировать: Что я уже пробовал:
Я рассмотрел транзакции как вариант, но не могу найти способ заставить транзакцию ожидать обновления маркера / Не могу заставить код ожидать транзакции.
// Must refresh token in a transaction, to prevent multiple simultaneous refreshes
await tokenRef.transaction(async aToken => {
console.log("got token", aToken);
if (aToken) { // Make sure the token was not deleted
let tokenObj = this.client.accessToken.create(aToken);
console.log("token object", tokenObj);
console.log("expired", expired(tokenObj));
if (expired(tokenObj)) { // Re-check expiry
try {
const newToken = await this.getAccessToken(token.token.refresh_token, 'refresh_token');
console.log('Refresh Token Result', newToken.token);
console.log('Expires At', newToken.token.expires_at);
return newToken;
} catch (e) {
console.warn("Failed to refresh token", e);
return null; // Failed to refresh
}
}
console.log("not expired, not modifying", aToken);
return aToken;
}
return null;
});
Распечатывает:
получил токен null
получил токен {some_token_here}
объект токена {some object}
истек true
и затем из более поздней части кода, используя токен доступа, я получаю ошибку 401 (пытаясь получить доступ к третьей стороне). Это никогда не достигает refresh token result
.