如果 Firebase 用戶端應用程式會與自訂後端伺服器通訊,您可能需要在該伺服器上識別目前登入的使用者。如要安全地執行這項操作,請在使用者成功登入後,使用 HTTPS 將使用者的 ID 權杖傳送至伺服器。接著,在伺服器上驗證 ID 權杖的完整性和真實性,並從中擷取 uid
。您可以使用以這種方式傳送的 uid
,在伺服器上安全識別目前登入的使用者。
事前準備
如要使用 Firebase Admin SDK 驗證 ID 權杖,您必須擁有服務帳戶。如要進一步瞭解如何使用服務帳戶初始化 Admin SDK,請參閱 Admin SDK 設定說明。
在用戶端上擷取 ID 權杖
使用者或裝置成功登入後,Firebase 會建立對應的 ID 權杖,用來識別使用者/裝置,並授予存取多項資源的權限,例如 Firebase Realtime Database 和 Cloud Storage。您可以在自訂後端伺服器上重複使用該 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
// ...
}];
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
});
取得 ID 權杖後,您可以將該 JWT 傳送至後端,並使用 Firebase Admin SDK 驗證,或使用第三方 JWT 程式庫 (如果伺服器是以 Firebase 不支援的語言編寫)。
使用 Firebase Admin SDK 驗證 ID 權杖
Firebase Admin SDK 內建驗證及解碼 ID 權杖的方法。如果提供的 ID 權杖格式正確、未過期且已正確簽署,這個方法就會傳回已解碼的 ID 權杖。您可以從解碼後的權杖中擷取使用者或裝置的 uid
。
請按照 Admin SDK 設定說明,使用服務帳戶初始化 Admin SDK。接著,請使用 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']
Go
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。這個環境變數適用於在 Google 基礎架構上執行的程式碼,例如 App Engine和 Compute Engine。
使用第三方 JWT 程式庫驗證 ID 權杖
如果後端使用的語言不支援 Firebase Admin SDK,您還是可以驗證 ID 權杖。首先,找出適用於您語言的第三方 JWT 程式庫。然後驗證 ID 權杖的標頭、酬載和簽章。
驗證 ID 權杖的標頭是否符合下列限制:
ID 權杖標頭憑證附加資訊 | ||
---|---|---|
alg |
演算法 | "RS256" |
kid |
金鑰 ID |
必須對應至 https://www.googleapis.com/robot/v1/metadata/x509/securetoken@system.gserviceaccount.com 列出的其中一個公開金鑰 |
驗證 ID 權杖的酬載是否符合下列限制:
ID 權杖酬載憑證附加資訊 | ||
---|---|---|
exp |
到期時間 | 必須是未來的時間。時間以秒為單位,從世界標準時間指定期間開始計算。 |
iat |
核發時間 | 必須是過去的時間。時間以秒為單位,從世界標準時間指定期間開始計算。 |
aud |
目標對象 | 必須是 Firebase 專案 ID,也就是 Firebase 專案的專屬 ID,可在該專案主控台的網址中找到。 |
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
。