Как проверить токены идентификатора

Если клиентское приложение Firebase взаимодействует с собственным серверным приложением, вам может понадобиться идентифицировать пользователя, вошедшего в аккаунт, на этом сервере. Чтобы сделать это безопасно, после успешного входа отправьте идентификатор пользователя на свой сервер по протоколу HTTPS. Затем на сервере проверьте целостность и подлинность токена идентификатора и извлеките из него uid. Вы можете использовать uid, переданный таким образом, чтобы безопасно идентифицировать пользователя, вошедшего в аккаунт на вашем сервере.

Подготовка

Чтобы проверять токены идентификаторов с помощью Firebase Admin SDK, вам понадобится сервисный аккаунт. Чтобы узнать, как инициализировать Admin SDK с помощью сервисного аккаунта, следуйте инструкциям по настройке Admin SDK.

Как получать токены идентификаторов на клиентах

Когда пользователь или устройство успешно входит в аккаунт, Firebase создает соответствующий токен идентификатора, который уникальным образом идентифицирует пользователя или устройство и предоставляет ему доступ к различным ресурсам, таким как Firebase Realtime Database и Cloud Storage. Вы можете повторно использовать этот токен идентификатора, чтобы идентифицировать пользователя или устройство на своем сервере. Чтобы получить токен идентификатора от клиента, убедитесь, что пользователь вошел в аккаунт, а затем получите токен идентификатора от вошедшего в аккаунт пользователя:

iOS+

Objective-C
FIRUser *currentUser = [FIRAuth auth].currentUser;
[currentUser getIDTokenForcingRefresh:YES
                           completion:^(NSString *_Nullable idToken,
                                        NSError *_Nullable error) {
          if (error) {
            // Handle error
            return;
          }

          // Send token to your backend via HTTPS
          // ...
}];
Swift
let currentUser = FIRAuth.auth()?.currentUser
currentUser?.getIDTokenForcingRefresh(true) { idToken, error in
  if let error = error {
    // Handle error
    return;
  }

  // Send token to your backend via HTTPS
  // ...
}

Android

FirebaseUser mUser = FirebaseAuth.getInstance().getCurrentUser();
mUser.getIdToken(true)
    .addOnCompleteListener(new OnCompleteListener<GetTokenResult>() {
        public void onComplete(@NonNull Task<GetTokenResult> task) {
            if (task.isSuccessful()) {
                String idToken = task.getResult().getToken();
                // Send token to your backend via HTTPS
                // ...
            } else {
                // Handle error -> task.getException();
            }
        }
    });

Unity

Firebase.Auth.FirebaseUser user = auth.CurrentUser;
user.TokenAsync(true).ContinueWith(task => {
  if (task.IsCanceled) {
    Debug.LogError("TokenAsync was canceled.");
   return;
  }

  if (task.IsFaulted) {
    Debug.LogError("TokenAsync encountered an error: " + task.Exception);
    return;
  }

  string idToken = task.Result;

  // Send token to your backend via HTTPS
  // ...
});

C++

firebase::auth::User user = auth->current_user();
if (user.is_valid()) {
  firebase::Future<std::string> idToken = user.GetToken(true);

  // Send token to your backend via HTTPS
  // ...
}

Веб-приложение

firebase.auth().currentUser.getIdToken(/* forceRefresh */ true).then(function(idToken) {
  // Send token to your backend via HTTPS
  // ...
}).catch(function(error) {
  // Handle error
});

Получив токен идентификатора, вы можете отправить JSON Web Token (JWT) на серверную часть и проверить его с помощью Firebase Admin SDK или сторонней библиотеки JWT, если сервер написан на языке, который не поддерживается Firebase.

Как проверить токены идентификаторов с помощью Firebase Admin SDK

В Firebase Admin SDK есть встроенный метод для проверки и декодирования токенов идентификаторов. Если предоставленный токен идентификатора имеет правильный формат, не просрочен и подписан надлежащим образом, метод возвращает декодированный токен идентификатора. Вы можете получить uid пользователя или устройства из декодированного токена.

Следуя инструкциям по настройке Admin SDK, инициализируйте Admin SDK с помощью сервисного аккаунта. Затем используйте метод verifyIdToken(), чтобы проверить токен идентификатора:

Node.js

// idToken comes from the client app
getAuth()
  .verifyIdToken(idToken)
  .then((decodedToken) => {
    const uid = decodedToken.uid;
    // ...
  })
  .catch((error) => {
    // Handle error
  });

Java

// idToken comes from the client app (shown above)
FirebaseToken decodedToken = FirebaseAuth.getInstance().verifyIdToken(idToken);
String uid = decodedToken.getUid();

Python

# id_token comes from the client app (shown above)

decoded_token = auth.verify_id_token(id_token)
uid = decoded_token['uid']

Проложить маршрут

client, err := app.Auth(ctx)
if err != nil {
	log.Fatalf("error getting Auth client: %v\n", err)
}

token, err := client.VerifyIDToken(ctx, idToken)
if err != nil {
	log.Fatalf("error verifying ID token: %v\n", err)
}

log.Printf("Verified ID token: %v\n", token)

C#

FirebaseToken decodedToken = await FirebaseAuth.DefaultInstance
    .VerifyIdTokenAsync(idToken);
string uid = decodedToken.Uid;

Для проверки токена идентификатора требуется идентификатор проекта. Firebase Admin SDK пытается получить идентификатор проекта одним из следующих способов:

  • Если SDK был инициализирован с явным вариантом projectId, SDK использует значение этого варианта.
  • Если SDK был инициализирован с учетными данными сервисного аккаунта, SDK использует поле project_id объекта JSON сервисного аккаунта.
  • Если задана переменная среды GOOGLE_CLOUD_PROJECT, SDK использует ее значение в качестве идентификатора проекта. Эта переменная среды доступна для кода, выполняемого в инфраструктуре Google, например в App Engine и Compute Engine.

Как проверить токены идентификаторов с помощью сторонней библиотеки JWT

Если ваш сервер написан на языке, который не поддерживается Firebase Admin SDK, вы все равно можете проверять токены идентификатора. Сначала найдите стороннюю библиотеку JWT для своего языка. Затем проверьте заголовок, полезную нагрузку и подпись токена идентификатора.

Убедитесь, что заголовок токена идентификатора соответствует следующим ограничениям:

Заявления в заголовке токена идентификатора
alg Алгоритм "RS256"
kid Идентификатор ключа Должен соответствовать одному из открытых ключей, перечисленных на странице https://www.googleapis.com/robot/v1/metadata/x509/securetoken@system.gserviceaccount.com.

Убедитесь, что полезная нагрузка токена идентификатора соответствует следующим ограничениям:

Заявления в полезной нагрузке токена идентификатора
exp Срок действия Должна быть в будущем. Время измеряется в секундах с начала эпохи UNIX.
iat Время выпуска Должна быть в прошлом. Время измеряется в секундах с начала эпохи UNIX.
aud Аудитория Идентификатор проекта Firebase – уникальный идентификатор проекта Firebase, который можно найти в URL консоли этого проекта.
iss Издатель Должен иметь значение "https://securetoken.google.com/<projectId>", где <projectId> – это тот же идентификатор проекта, который используется для aud выше.
sub Субъект Должна быть непустой строкой и представлять собой uid пользователя или устройства.
auth_time Время аутентификации Должна быть в прошлом. Время, когда пользователь прошел аутентификацию.

Наконец, убедитесь, что токен идентификатора подписан закрытым ключом, соответствующим утверждению kid токена. Возьмите открытый ключ из https://www.googleapis.com/robot/v1/metadata/x509/securetoken@system.gserviceaccount.com и используйте библиотеку JWT для проверки подписи. Чтобы узнать, когда нужно обновить открытые ключи, используйте значение max-age в заголовке Cache-Control ответа от этой конечной точки.

Если все проверки прошли успешно, вы можете использовать поле subject (sub) токена идентификатора в качестве поля uid соответствующего пользователя или устройства.