# #android #firebase #firebase-authentication #google-signin
Вопрос:
Я хочу выйти со всех устройств по нажатию кнопки для входа в Google Firebase. Возможно ли это? Если да, пожалуйста, поделитесь документом или примером кода.
Не удалось найти никакого решения для этого в stackoverflow.
Код для выхода из текущего устройства
FirebaseAuth.getInstance().signOut()
Это работает только для текущего устройства, но не для всех устройств.
Ответ №1:
Чтобы отозвать токены обновления для данного пользователя (что не позволит клиентам запрашивать новый токен идентификатора), вы можете:
- Измените пароль пользователя
- Отключите пользователя с помощью пакета SDK сервера Firebase и обновите
disabled
свойство. Для узла вы бы использовалиAuth#updateUser
методfirebase-admin
. - Отмените токены вручную с помощью пакета SDK сервера Firebase. Для узла вы бы использовали
Auth#revokeRefreshTokens()
методfirebase-admin
.
Здесь важно отметить, что эти методы не аннулируют уже выпущенные токены. Эти токены будут считаться действительными в течение часа, если вы явно не проверите, были ли они отозваны. Вы можете несколько решить эту проблему, используя FirebaseUser#getIdToken(true)
, когда вы обнаружите, что пользователь открыл приложение, но уже вошел в систему. Этот метод пытается получить новый маркер идентификатора, а не просто использовать кэшированный маркер идентификатора — просто убедитесь, что обработали случай, когда маркер обновления был признан недействительным.
Из вышеперечисленных вариантов я бы рекомендовал последний вариант и сделал его доступным с помощью вызываемой облачной функции.
Код на стороне сервера, размещенный в облачных функциях:
import * as functions from "firebase-functions";
import * as admin from "firebase-admin";
export const revokeRefreshTokens = functions.https.onCall((data, context) => {
if (!context.auth) {
throw new functions.https.HttpsError(
"failed-precondition",
"The function must be called while authenticated."
);
}
// New optional feature: Firebase App Check
if (context.app === undefined) {
throw new functions.https.HttpsError(
"failed-precondition",
"The function must be called from an App Check verified app."
);
}
const uid = context.auth.uid;
return admin
.auth()
.revokeRefreshTokens(uid)
.then(() => {
return admin.auth().getUser(uid);
})
.then((userRecord) => {
// send back a response with the UID and time tokens were revoked
const timestamp = new Date(userRecord.tokensValidAfterTime).getTime();
return { uid, revokedAt: timestamp }
})
.catch((err) => {
// rethrow any errors as HttpsError for clients
throw new functions.https.HttpsError("unknown", err.code || err.message);
});
});
Код на стороне клиента:
public void revokeRefreshTokens() {
return FirebaseFunctions.getInstance()
.getHttpsCallable("revokeRefreshTokens")
.call(data)
.continueWith(new Continuation<HttpsCallableResult, Void>() {
@Override
public String then(@NonNull Task<HttpsCallableResult> task) throws Exception {
if (task.isSuccessful()) {
// revoked successfully, end this sign-in session
FirebaseAuth.getInstance().signOut()
} else {
// failed to revoke, rethrow error
throw task.getException();
}
}
});
}
Комментарии:
1. Отзыв токена обновления не позволит клиенту чеканить новые идентификационные токены, но не сделает недействительными существующие идентификационные токены. Вот почему в документации Firebase показано, как также проверить внутренние службы (например, правила безопасности базы данных), была ли учетная запись отключена/вышла из системы: firebase.google.com/docs/auth/admin/. …
2. @FrankvanPuffelen Это важное уточнение, которое я ошибочно пропустил. Я добавил это к ответу.