Join us for Firebase Summit on November 10, 2021. Tune in to learn how Firebase can help you accelerate app development, release with confidence, and scale with ease. Register

驗證 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
getAuth()
  .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相應的用戶或設備。