Firebaseクライアントアプリがカスタムバックエンドサーバーと通信する場合は、そのサーバーで現在ログインしているユーザーを特定する必要がある場合があります。これを安全に行うには、サインインが成功した後、HTTPSを使用してユーザーのIDトークンをサーバーに送信します。次に、サーバー上でIDトークンの整合性と信頼性を確認し、そこからuid
を取得します。この方法で送信されたuid
を使用して、サーバーで現在サインインしているユーザーを安全に識別できます。
あなたが始める前に
Firebase Admin SDKでIDトークンを確認するには、サービスアカウントが必要です。サービスアカウントを使用してAdminSDKを初期化する方法の詳細については、 AdminSDKのセットアップ手順に従ってください。
クライアントでIDトークンを取得する
ユーザーまたはデバイスが正常にサインインすると、Firebaseはそれらを一意に識別する対応するIDトークンを作成し、Firebase RealtimeDatabaseやCloudStorageなどのいくつかのリソースへのアクセスを許可します。そのIDトークンを再利用して、カスタムバックエンドサーバー上のユーザーまたはデバイスを識別できます。クライアントからIDトークンを取得するには、ユーザーがサインインしていることを確認してから、サインインしているユーザーからIDトークンを取得します。
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
// ...
}];
迅速
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
// ...
}
アンドロイド
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();
}
}
});
団結
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 != nullptr) {
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
});
IDトークンを取得したら、そのJWTをバックエンドに送信し、Firebase Admin SDKを使用して検証するか、サーバーがFirebaseでネイティブにサポートされていない言語で記述されている場合はサードパーティのJWTライブラリを使用して検証できます。
Firebase AdminSDKを使用してIDトークンを確認する
Firebase Admin SDKには、IDトークンを確認およびデコードするための組み込みのメソッドがあります。提供されたIDトークンの形式が正しく、有効期限が切れておらず、適切に署名されている場合、メソッドはデコードされたIDトークンを返します。デコードされたトークンからユーザーまたはデバイスのuid
を取得できます。
Admin SDKのセットアップ手順に従って、サービスアカウントでAdminSDKを初期化します。次に、 verifyIdToken()
メソッドを使用してIDトークンを検証します。
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;
IDトークンの検証にはプロジェクトIDが必要です。 Firebase Admin SDKは、次のいずれかの方法でプロジェクトIDを取得しようとします。
- SDKが明示的な
projectId
アプリオプションで初期化された場合、SDKはそのオプションの値を使用します。 - SDKがサービスアカウントの資格情報で初期化された場合、SDKはサービスアカウントのJSONオブジェクトの
project_id
フィールドを使用します。 -
GOOGLE_CLOUD_PROJECT
環境変数が設定されている場合、SDKはその値をプロジェクトIDとして使用します。この環境変数は、AppEngineやComputeEngineなどのGoogleインフラストラクチャで実行されているコードで使用できます。
サードパーティのJWTライブラリを使用してIDトークンを確認する
バックエンドがFirebaseAdmin SDKでサポートされていない言語である場合でも、IDトークンを確認できます。まず、ご使用の言語に対応するサードパーティのJWTライブラリを見つけます。次に、IDトークンのヘッダー、ペイロード、および署名を確認します。
IDトークンのヘッダーが次の制約に準拠していることを確認します。
IDトークンヘッダーの主張 | ||
---|---|---|
alg | アルゴリズム | "RS256" |
kid | キーID | https://www.googleapis.com/robot/v1/metadata/x509/securetoken@system.gserviceaccount.com にリストされている公開鍵の1つに対応している必要があります |
IDトークンのペイロードが次の制約に準拠していることを確認します。
IDトークンのペイロードクレーム | ||
---|---|---|
exp | 有効期限 | 将来でなければなりません。時間は、UNIXエポックからの秒数で測定されます。 |
iat | 発行-時間 | 過去でなければなりません。時間は、UNIXエポックからの秒数で測定されます。 |
aud | 観客 | FirebaseプロジェクトIDである必要があります。これは、Firebaseプロジェクトの一意の識別子であり、そのプロジェクトのコンソールのURLにあります。 |
iss | 発行者 | "https://securetoken.google.com/<projectId>" である必要があります。ここで、 <projectId> は上記のaud に使用されたものと同じプロジェクトIDです。 |
sub | 主題 | 空でない文字列である必要があり、ユーザーまたはデバイスのuid である必要があります。 |
auth_time | 認証時間 | 過去でなければなりません。ユーザーが認証した時刻。 |
最後に、IDトークンがトークンのkid
の主張に対応する秘密鍵によって署名されていることを確認します。 https://www.googleapis.com/robot/v1/metadata/x509/securetoken@system.gserviceaccount.com
から公開鍵を取得し、JWTライブラリを使用して署名を確認します。そのエンドポイントからの応答のCache-Control
ヘッダーにあるmax-age
の値を使用して、公開鍵をいつ更新するかを確認します。
上記のすべての検証が成功した場合、IDトークンのサブジェクト( sub
)を対応するユーザーまたはデバイスのuid
として使用できます。