如果 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。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
。