驗證 ID 令牌

如果您的 Firebase 客戶端應用與自定義後端服務器通信,您可能需要識別該服務器上當前登錄的用戶。要安全地執行此操作,請在成功登錄後使用 HTTPS 將用戶的 ID 令牌發送到您的服務器。然後,在服務器上,驗證令牌的ID的完整性和真實性,並檢索uid從它。您可以使用uid以這種方式傳遞到安全地識別當前登錄的用戶在服務器上。

在你開始之前

要使用 Firebase Admin SDK 驗證 ID 令牌,您必須擁有一個服務帳號。按照管理SDK安裝說明有關如何與服務帳戶初始化管理SDK的詳細信息。

檢索客戶端上的 ID 令牌

當用戶或設備成功登錄時,Firebase 會創建一個相應的 ID 令牌,用於唯一標識他們並授予他們訪問多種資源的權限,例如 Firebase 實時數據庫和 Cloud Storage。您可以重複使用該 ID 令牌來識別自定義後端服務器上的用戶或設備。要從客戶端檢索 ID 令牌,請確保用戶已登錄,然後從登錄用戶處獲取 ID 令牌:

IOS

目標-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 Admin SDK 驗證 ID 令牌

Firebase Admin SDK 具有用於驗證和解碼 ID 令牌的內置方法。如果提供的 ID 令牌具有正確的格式、未過期且已正確簽名,則該方法返回解碼後的 ID 令牌。你可以抓住的uid從解碼令牌的用戶或設備。

按照管理SDK安裝說明與服務帳戶來初始化管理員SDK。然後,使用verifyIdToken()方法來驗證ID令牌:

節點.js

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

爪哇

// 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使用project_id服務帳戶JSON對象的領域。
  • 如果GOOGLE_CLOUD_PROJECT環境變量設置,該SDK使用其作為該項目的ID值。此環境變量可用於在 Google 基礎架構(例如 App Engine 和 Compute Engine)上運行的代碼。

使用第三方 JWT 庫驗證 ID 令牌

如果您的後端使用 Firebase Admin SDK 不支持的語言,您仍然可以驗證 ID 令牌。首先,找到適合你的語言第三方JWT庫。然後,驗證 ID 令牌的標頭、有效負載和簽名。

驗證 ID 令牌的標頭是否符合以下約束:

ID 令牌標頭聲明
alg算法"RS256"
kid鑰匙編號必須對應於在列出的公開密鑰的一個https://www.googleapis.com/robot/v1/metadata/x509/securetoken@system.gserviceaccount.com

驗證 ID 令牌的有效負載符合以下約束:

ID 令牌有效載荷聲明
exp到期時間必須在未來。時間以 UNIX 時代以來的秒為單位。
iat發行時間應該是過去。時間以 UNIX 時代以來的秒為單位。
aud觀眾必須是您的 Firebase 項目 ID,即您的 Firebase 項目的唯一標識符,可以在該項目的控制台網址中找到。
iss發行人必須是"https://securetoken.google.com/<projectId>"其中<projectId>是用於相同項目ID aud上方。
sub主題必須是一個非空字符串,並且必須是uid ,用戶或設備。
auth_time認證時間應該是過去。用戶進行身份驗證的時間。

最後,確保ID令牌對應於令牌的私鑰簽名kid要求。抓住從公鑰https://www.googleapis.com/robot/v1/metadata/x509/securetoken@system.gserviceaccount.com並使用JWT庫來驗證簽名。利用價值max-ageCache-Control從端點響應的頭,知道什麼時候刷新公鑰。

如果所有上述驗證是成功的,則可以使用所述受檢者( sub令牌作為所述ID的) uid相應的用戶或設備。