如果您的 Firebase 用戶端應用程式與自訂後端伺服器通訊,您可能需要在該伺服器上找出目前登入的使用者。為了以安全的方式完成此作業,請在成功登入後,使用 HTTPS 將使用者的 ID 權杖傳送至您的伺服器。接著,在伺服器上驗證 ID 權杖的完整性和真實性,並從中擷取 uid
。您可以使用以這種方式傳輸的 uid
,安全地識別伺服器上目前登入的使用者。
事前準備
如要透過 Firebase Admin SDK 驗證 ID 權杖,您必須擁有服務帳戶。請參閱「Admin SDK 設定操作說明」,進一步瞭解如何使用服務帳戶初始化 Admin SDK。
在用戶端擷取 ID 權杖
當使用者或裝置成功登入時,Firebase 會建立對應的 ID 符記來識別使用者,並授予他們多項資源的存取權,例如 Firebase 即時資料庫和 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 進行驗證。如果伺服器是以 Firebase 不支援的語言編寫,則可以使用第三方 JWT 程式庫進行驗證。
使用 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。在 App Engine 和 Compute Engine 等 Google 基礎架構上執行的程式碼,都能使用這個環境變數。
使用第三方 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 |
到期時間 | 必須是未來的日期。時間以秒為單位,從 UNIX 紀元起算。 |
iat |
核發時間 | 必須設為過去的時間。時間以秒為單位,從 UNIX 紀元起算。 |
aud |
目標對象 | 必須是 Firebase 專案 ID,也就是 Firebase 專案的專屬 ID,你可以在該專案控制台的網址中找到這個 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
。