Nếu ứng dụng khách Firebase của bạn giao tiếp với một máy chủ phụ trợ tuỳ chỉnh, thì bạn có thể cần xác định người dùng hiện đã đăng nhập trên máy chủ đó. Để thực hiện việc này một cách an toàn, sau khi đăng nhập thành công, hãy gửi mã thông báo nhận dạng của người dùng đến máy chủ của bạn bằng HTTPS. Sau đó, trên máy chủ, hãy xác minh tính toàn vẹn và tính xác thực của mã thông báo nhận dạng rồi truy xuất uid từ mã đó. Bạn có thể sử dụng uid được truyền theo cách này để xác định một cách an toàn người dùng hiện đã đăng nhập trên máy chủ của bạn.
Trước khi bắt đầu
Để xác minh mã thông báo nhận dạng bằng SDK của Firebase dành cho quản trị viên, bạn phải có một tài khoản dịch vụ. Hãy làm theo hướng dẫn thiết lập SDK dành cho quản trị viên để biết thêm thông tin về cách khởi chạy SDK dành cho quản trị viên bằng tài khoản dịch vụ.
Truy xuất mã thông báo nhận dạng trên máy khách
Khi người dùng hoặc thiết bị đăng nhập thành công, Firebase sẽ tạo một mã thông báo nhận dạng tương ứng để xác định riêng biệt người dùng hoặc thiết bị đó và cấp cho họ quyền truy cập vào một số tài nguyên, chẳng hạn như Firebase Realtime Database và Cloud Storage. Bạn có thể sử dụng lại mã thông báo nhận dạng đó để xác định người dùng hoặc thiết bị trên máy chủ phụ trợ tuỳ chỉnh của mình. Để truy xuất mã thông báo nhận dạng từ máy khách, hãy đảm bảo người dùng đã đăng nhập rồi lấy mã thông báo nhận dạng từ người dùng đã đăng nhập:
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
// ...
}
Web
firebase.auth().currentUser.getIdToken(/* forceRefresh */ true).then(function(idToken) {
// Send token to your backend via HTTPS
// ...
}).catch(function(error) {
// Handle error
});
Sau khi có mã thông báo nhận dạng, bạn có thể gửi Mã thông báo web JSON (JWT) đó đến phần phụ trợ và xác thực mã đó bằng SDK quản trị Firebase hoặc bằng thư viện JWT bên thứ ba nếu máy chủ của bạn được viết bằng một ngôn ngữ mà Firebase không hỗ trợ gốc.
Xác minh mã thông báo nhận dạng bằng SDK của Firebase dành cho quản trị viên
SDK của Firebase dành cho quản trị viên có một phương thức tích hợp để xác minh và giải mã mã thông báo nhận dạng. Nếu mã thông báo nhận dạng được cung cấp có đúng định dạng, chưa hết hạn và được ký đúng cách, thì phương thức này sẽ trả về mã thông báo nhận dạng đã giải mã. Bạn có thể lấy uid của người dùng hoặc thiết bị từ mã thông báo đã giải mã.
Hãy làm theo hướng dẫn thiết lập SDK dành cho quản trị viên để khởi động SDK dành cho quản trị viên bằng tài khoản dịch vụ. Sau đó, hãy sử dụng phương thức verifyIdToken() để xác minh mã thông báo nhận dạng:
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;
Việc xác minh mã thông báo nhận dạng yêu cầu phải có mã dự án. SDK của Firebase dành cho quản trị viên cố gắng lấy mã dự án thông qua một trong các phương thức sau:
- Nếu SDK được khởi chạy bằng một tuỳ chọn ứng dụng
projectIdrõ ràng, thì SDK sẽ sử dụng giá trị của tuỳ chọn đó. - Nếu SDK được khởi chạy bằng thông tin đăng nhập tài khoản dịch vụ, thì SDK sẽ sử dụng trường
project_idcủa đối tượng JSON tài khoản dịch vụ. - Nếu biến môi trường
GOOGLE_CLOUD_PROJECTđược thiết lập, thì SDK sẽ sử dụng giá trị của biến đó làm mã dự án. Biến môi trường này dùng được cho mã chạy trên cơ sở hạ tầng của Google, chẳng hạn như App Engine và Compute Engine.
Xác minh mã thông báo nhận dạng bằng thư viện JWT bên thứ ba
Nếu phần phụ trợ của bạn được viết bằng một ngôn ngữ mà SDK quản trị Firebase không hỗ trợ, thì bạn vẫn có thể xác minh mã thông báo nhận dạng. Trước tiên, hãy tìm một thư viện JWT bên thứ ba cho ngôn ngữ của bạn. Sau đó, hãy xác minh tiêu đề, phần dữ liệu thực tế và chữ ký của mã thông báo nhận dạng.
Xác minh tiêu đề của mã thông báo nhận dạng tuân thủ các ràng buộc sau:
| Xác nhận tiêu đề của mã thông báo nhận dạng | ||
|---|---|---|
alg |
Thuật toán | "RS256" |
kid |
Mã khoá |
Phải tương ứng với một trong các khoá công khai được liệt kê tại
https://www.googleapis.com/robot/v1/metadata/x509/securetoken@system.gserviceaccount.com
|
Xác minh phần dữ liệu thực tế của mã thông báo nhận dạng tuân thủ các ràng buộc sau:
| Xác nhận phần dữ liệu thực tế của mã thông báo nhận dạng | ||
|---|---|---|
exp |
Thời gian hết hạn | Phải là thời gian trong tương lai. Thời gian được tính bằng giây kể từ thời điểm bắt đầu thời gian Unix. |
iat |
Thời gian phát hành | Phải là thời gian trong quá khứ. Thời gian được tính bằng giây kể từ thời điểm bắt đầu thời gian Unix. |
aud |
Đối tượng | Phải là mã dự án Firebase của bạn, giá trị nhận dạng riêng biệt cho dự án Firebase của bạn. Bạn có thể tìm thấy mã này trong URL của bảng điều khiển dự án đó. |
iss |
Tổ chức phát hành |
Phải là "https://securetoken.google.com/<projectId>",
trong đó <projectId> là cùng một mã dự án được dùng cho
aud ở trên.
|
sub |
Chủ đề |
Phải là một chuỗi không trống và phải là uid của người dùng hoặc
thiết bị.
|
auth_time
|
Thời gian xác thực | Phải là thời gian trong quá khứ. Thời gian người dùng xác thực. |
Cuối cùng, hãy đảm bảo rằng mã thông báo nhận dạng được ký bằng khoá riêng tư tương ứng với xác nhận kid của mã thông báo. Lấy khoá công khai từ https://www.googleapis.com/robot/v1/metadata/x509/securetoken@system.gserviceaccount.com rồi sử dụng thư viện JWT để xác minh chữ ký. Sử dụng giá trị của max-age trong tiêu đề Cache-Control của phản hồi từ điểm cuối đó để biết thời điểm làm mới khoá công khai.
Nếu tất cả các bước xác minh ở trên đều thành công, thì bạn có thể sử dụng chủ đề (sub) của mã thông báo nhận dạng làm uid của người dùng hoặc thiết bị tương ứng.