Catch up on everything announced at Firebase Summit, and learn how Firebase can help you accelerate app development and run your app with confidence. Learn More

Tạo mã thông báo tùy chỉnh

Sử dụng bộ sưu tập để sắp xếp ngăn nắp các trang Lưu và phân loại nội dung dựa trên lựa chọn ưu tiên của bạn.

Firebase cung cấp cho bạn toàn quyền kiểm soát xác thực bằng cách cho phép bạn xác thực người dùng hoặc thiết bị bằng cách sử dụng Mã thông báo web JSON (JWT) an toàn. Bạn tạo các mã thông báo này trên máy chủ của mình, chuyển chúng trở lại thiết bị khách, sau đó sử dụng chúng để xác thực thông qua phương thức signInWithCustomToken() .

Để đạt được điều này, bạn phải tạo một điểm cuối máy chủ chấp nhận thông tin đăng nhập—chẳng hạn như tên người dùng và mật khẩu—và, nếu thông tin đăng nhập hợp lệ, trả về JWT tùy chỉnh. JWT tùy chỉnh được trả về từ máy chủ của bạn sau đó có thể được thiết bị khách sử dụng để xác thực bằng Firebase ( iOS+ , Android , web ). Sau khi được xác thực, danh tính này sẽ được sử dụng khi truy cập các dịch vụ Firebase khác, chẳng hạn như Cơ sở dữ liệu thời gian thực Firebase và Lưu trữ đám mây. Hơn nữa, nội dung của JWT sẽ có sẵn trong đối tượng auth trong Quy tắc cơ sở dữ liệu thời gian thực của bạn và đối tượng request.auth trong Quy tắc bảo mật lưu trữ đám mây của bạn.

Bạn có thể tạo mã thông báo tùy chỉnh bằng SDK quản trị Firebase hoặc bạn có thể sử dụng thư viện JWT của bên thứ ba nếu máy chủ của bạn được viết bằng ngôn ngữ mà Firebase không hỗ trợ.

Trước khi bắt đầu

Mã thông báo tùy chỉnh là JWT đã ký trong đó khóa riêng được sử dụng để ký thuộc về tài khoản dịch vụ của Google. Có một số cách để chỉ định tài khoản dịch vụ của Google mà SDK quản trị Firebase sẽ sử dụng để ký mã thông báo tùy chỉnh:

  • Sử dụng tệp JSON của tài khoản dịch vụ -- Phương pháp này có thể được sử dụng trong mọi môi trường nhưng yêu cầu bạn đóng gói tệp JSON của tài khoản dịch vụ cùng với mã của bạn. Phải đặc biệt cẩn thận để đảm bảo rằng tệp JSON của tài khoản dịch vụ không bị lộ ra bên ngoài.
  • Cho phép SDK quản trị khám phá tài khoản dịch vụ -- Phương pháp này có thể được sử dụng trong các môi trường do Google quản lý, chẳng hạn như Google Cloud Function và App Engine. Bạn có thể phải định cấu hình một số quyền bổ sung thông qua Google Cloud Console.
  • Sử dụng ID tài khoản dịch vụ -- Khi được sử dụng trong môi trường do Google quản lý, phương pháp này sẽ ký mã thông báo bằng cách sử dụng khóa của tài khoản dịch vụ được chỉ định. Tuy nhiên, nó sử dụng một dịch vụ web từ xa và bạn có thể phải định cấu hình các quyền bổ sung cho tài khoản dịch vụ này thông qua Google Cloud Console.

Sử dụng tệp JSON của tài khoản dịch vụ

Tệp JSON của tài khoản dịch vụ chứa tất cả thông tin tương ứng với tài khoản dịch vụ (bao gồm cả khóa riêng RSA). Chúng có thể được tải xuống từ bảng điều khiển Firebase. Làm theo hướng dẫn thiết lập SDK quản trị để biết thêm thông tin về cách khởi tạo SDK quản trị bằng tệp JSON của tài khoản dịch vụ.

Phương pháp khởi tạo này phù hợp với nhiều loại triển khai SDK dành cho quản trị viên. Ngoài ra, nó cho phép SDK quản trị tạo và ký mã thông báo tùy chỉnh cục bộ mà không cần thực hiện bất kỳ lệnh gọi API từ xa nào. Hạn chế chính của phương pháp này là nó yêu cầu bạn đóng gói tệp JSON của tài khoản dịch vụ cùng với mã của bạn. Cũng xin lưu ý rằng khóa riêng tư trong tệp JSON của tài khoản dịch vụ là thông tin nhạy cảm và phải đặc biệt cẩn thận để giữ bí mật khóa này. Cụ thể, không thêm các tệp JSON của tài khoản dịch vụ vào kiểm soát phiên bản công khai.

Cho phép SDK quản trị khám phá tài khoản dịch vụ

Nếu mã của bạn được triển khai trong môi trường do Google quản lý, thì SDK dành cho quản trị viên có thể cố gắng tự động phát hiện phương tiện để ký mã thông báo tùy chỉnh:

  • Nếu mã của bạn được triển khai trong môi trường tiêu chuẩn của Máy ứng dụng dành cho Java, Python hoặc Go, SDK quản trị có thể sử dụng dịch vụ Nhận dạng ứng dụng có trong môi trường đó để ký mã thông báo tùy chỉnh. Dịch vụ Nhận dạng ứng dụng ký dữ liệu bằng tài khoản dịch vụ do Google App Engine cung cấp cho ứng dụng của bạn.

  • Nếu mã của bạn được triển khai trong một số môi trường được quản lý khác (ví dụ: Google Cloud Function, Google Compute Engine), SDK quản trị Firebase có thể tự động phát hiện chuỗi ID tài khoản dịch vụ từ máy chủ siêu dữ liệu cục bộ . Sau đó, ID tài khoản dịch vụ được phát hiện sẽ được sử dụng cùng với dịch vụ IAM để ký mã thông báo từ xa.

Để sử dụng các phương thức ký này, hãy khởi tạo SDK bằng thông tin đăng nhập Mặc định của ứng dụng Google và không chỉ định chuỗi ID tài khoản dịch vụ:

Node.js

initializeApp();

Java

FirebaseApp.initializeApp();

con trăn

default_app = firebase_admin.initialize_app()

Đi

app, err := firebase.NewApp(context.Background(), nil)
if err != nil {
	log.Fatalf("error initializing app: %v\n", err)
}

C#

FirebaseApp.Create();

Để kiểm tra cục bộ cùng một mã, hãy tải xuống tệp JSON của tài khoản dịch vụ và đặt biến môi trường GOOGLE_APPLICATION_CREDENTIALS để trỏ tới tệp đó.

Nếu SDK quản trị Firebase phải khám phá chuỗi ID tài khoản dịch vụ, SDK sẽ làm như vậy khi mã của bạn tạo mã thông báo tùy chỉnh lần đầu tiên. Kết quả được lưu vào bộ nhớ cache và được sử dụng lại cho các hoạt động ký mã thông báo tiếp theo. ID tài khoản dịch vụ được phát hiện tự động thường là một trong những tài khoản dịch vụ mặc định do Google Cloud cung cấp:

Giống như ID tài khoản dịch vụ được chỉ định rõ ràng, ID tài khoản dịch vụ tự động phát hiện phải có quyền iam.serviceAccounts.signBlob để việc tạo mã thông báo tùy chỉnh hoạt động. Bạn có thể phải sử dụng phần IAM và quản trị viên của Google Cloud Console để cấp các quyền cần thiết cho tài khoản dịch vụ mặc định. Xem phần khắc phục sự cố bên dưới để biết thêm chi tiết.

Sử dụng ID tài khoản dịch vụ

Để duy trì tính nhất quán giữa các phần khác nhau trong ứng dụng của bạn, bạn có thể chỉ định ID tài khoản dịch vụ có khóa sẽ được sử dụng để ký mã thông báo khi chạy trong môi trường do Google quản lý. Điều này có thể làm cho các chính sách IAM trở nên đơn giản và an toàn hơn, đồng thời tránh phải đưa tệp JSON của tài khoản dịch vụ vào mã của bạn.

Bạn có thể tìm thấy ID tài khoản dịch vụ trong Google Cloud Console hoặc trong trường client_email của tệp JSON tài khoản dịch vụ đã tải xuống. ID tài khoản dịch vụ là các địa chỉ email có định dạng sau: <client-id>@<project-id>.iam.gserviceaccount.com . Chúng xác định duy nhất các tài khoản dịch vụ trong các dự án Firebase và Google Cloud.

Để tạo mã thông báo tùy chỉnh bằng ID tài khoản dịch vụ riêng, hãy khởi tạo SDK như hình bên dưới:

Node.js

initializeApp({
  serviceAccountId: 'my-client-id@my-project-id.iam.gserviceaccount.com',
});

Java

FirebaseOptions options = FirebaseOptions.builder()
    .setCredentials(GoogleCredentials.getApplicationDefault())
    .setServiceAccountId("my-client-id@my-project-id.iam.gserviceaccount.com")
    .build();
FirebaseApp.initializeApp(options);

con trăn

options = {
    'serviceAccountId': 'my-client-id@my-project-id.iam.gserviceaccount.com',
}
firebase_admin.initialize_app(options=options)

Đi

conf := &firebase.Config{
	ServiceAccountID: "my-client-id@my-project-id.iam.gserviceaccount.com",
}
app, err := firebase.NewApp(context.Background(), conf)
if err != nil {
	log.Fatalf("error initializing app: %v\n", err)
}

C#

FirebaseApp.Create(new AppOptions()
{
    Credential = GoogleCredential.GetApplicationDefault(),
    ServiceAccountId = "my-client-id@my-project-id.iam.gserviceaccount.com",
});

ID tài khoản dịch vụ không phải là thông tin nhạy cảm và do đó, việc tiếp xúc với chúng là không quan trọng. Tuy nhiên, để ký mã thông báo tùy chỉnh với tài khoản dịch vụ được chỉ định, SDK quản trị Firebase phải gọi một dịch vụ từ xa. Ngoài ra, bạn cũng phải đảm bảo rằng tài khoản dịch vụ mà SDK quản trị đang sử dụng để thực hiện cuộc gọi này {project-name}@appspot.gserviceaccount.com — có quyền iam.serviceAccounts.signBlob . Xem phần khắc phục sự cố bên dưới để biết thêm chi tiết.

Tạo mã thông báo tùy chỉnh bằng SDK quản trị Firebase

SDK quản trị Firebase có phương pháp tích hợp sẵn để tạo mã thông báo tùy chỉnh. Ở mức tối thiểu, bạn cần cung cấp một uid , có thể là bất kỳ chuỗi nào nhưng phải nhận dạng duy nhất người dùng hoặc thiết bị mà bạn đang xác thực. Những mã thông báo này hết hạn sau một giờ.

Node.js

const uid = 'some-uid';

getAuth()
  .createCustomToken(uid)
  .then((customToken) => {
    // Send token back to client
  })
  .catch((error) => {
    console.log('Error creating custom token:', error);
  });

Java

String uid = "some-uid";

String customToken = FirebaseAuth.getInstance().createCustomToken(uid);
// Send token back to client

con trăn

uid = 'some-uid'

custom_token = auth.create_custom_token(uid)

Đi

client, err := app.Auth(context.Background())
if err != nil {
	log.Fatalf("error getting Auth client: %v\n", err)
}

token, err := client.CustomToken(ctx, "some-uid")
if err != nil {
	log.Fatalf("error minting custom token: %v\n", err)
}

log.Printf("Got custom token: %v\n", token)

C#

var uid = "some-uid";

string customToken = await FirebaseAuth.DefaultInstance.CreateCustomTokenAsync(uid);
// Send token back to client

Bạn cũng có thể tùy ý chỉ định các xác nhận quyền sở hữu bổ sung được đưa vào mã thông báo tùy chỉnh. Ví dụ: bên dưới, trường premiumAccount đã được thêm vào mã thông báo tùy chỉnh, sẽ có sẵn trong các đối tượng auth / request.auth trong Quy tắc bảo mật của bạn:

Node.js

const userId = 'some-uid';
const additionalClaims = {
  premiumAccount: true,
};

getAuth()
  .createCustomToken(userId, additionalClaims)
  .then((customToken) => {
    // Send token back to client
  })
  .catch((error) => {
    console.log('Error creating custom token:', error);
  });

Java

String uid = "some-uid";
Map<String, Object> additionalClaims = new HashMap<String, Object>();
additionalClaims.put("premiumAccount", true);

String customToken = FirebaseAuth.getInstance()
    .createCustomToken(uid, additionalClaims);
// Send token back to client

con trăn

uid = 'some-uid'
additional_claims = {
    'premiumAccount': True
}

custom_token = auth.create_custom_token(uid, additional_claims)

Đi

client, err := app.Auth(context.Background())
if err != nil {
	log.Fatalf("error getting Auth client: %v\n", err)
}

claims := map[string]interface{}{
	"premiumAccount": true,
}

token, err := client.CustomTokenWithClaims(ctx, "some-uid", claims)
if err != nil {
	log.Fatalf("error minting custom token: %v\n", err)
}

log.Printf("Got custom token: %v\n", token)

C#

var uid = "some-uid";
var additionalClaims = new Dictionary<string, object>()
{
    { "premiumAccount", true },
};

string customToken = await FirebaseAuth.DefaultInstance
    .CreateCustomTokenAsync(uid, additionalClaims);
// Send token back to client

Tên mã thông báo tùy chỉnh dành riêng

Đăng nhập bằng mã thông báo tùy chỉnh trên máy khách

Sau khi tạo mã thông báo tùy chỉnh, bạn nên gửi mã đó đến ứng dụng khách của mình. Ứng dụng khách xác thực bằng mã thông báo tùy chỉnh bằng cách gọi signInWithCustomToken() :

iOS+

Mục tiêu-C
[[FIRAuth auth] signInWithCustomToken:customToken
                           completion:^(FIRAuthDataResult * _Nullable authResult,
                                        NSError * _Nullable error) {
  // ...
}];
Nhanh
Auth.auth().signIn(withCustomToken: customToken ?? "") { user, error in
  // ...
}

Android

mAuth.signInWithCustomToken(mCustomToken)
        .addOnCompleteListener(this, new OnCompleteListener<AuthResult>() {
            @Override
            public void onComplete(@NonNull Task<AuthResult> task) {
                if (task.isSuccessful()) {
                    // Sign in success, update UI with the signed-in user's information
                    Log.d(TAG, "signInWithCustomToken:success");
                    FirebaseUser user = mAuth.getCurrentUser();
                    updateUI(user);
                } else {
                    // If sign in fails, display a message to the user.
                    Log.w(TAG, "signInWithCustomToken:failure", task.getException());
                    Toast.makeText(CustomAuthActivity.this, "Authentication failed.",
                            Toast.LENGTH_SHORT).show();
                    updateUI(null);
                }
            }
        });

Đoàn kết

auth.SignInWithCustomTokenAsync(custom_token).ContinueWith(task => {
  if (task.IsCanceled) {
    Debug.LogError("SignInWithCustomTokenAsync was canceled.");
    return;
  }
  if (task.IsFaulted) {
    Debug.LogError("SignInWithCustomTokenAsync encountered an error: " + task.Exception);
    return;
  }

  Firebase.Auth.FirebaseUser newUser = task.Result;
  Debug.LogFormat("User signed in successfully: {0} ({1})",
      newUser.DisplayName, newUser.UserId);
});

C++

firebase::Future<firebase::auth::User*> result =
    auth->SignInWithCustomToken(custom_token);

Web version 8

firebase.auth().signInWithCustomToken(token)
  .then((userCredential) => {
    // Signed in
    var user = userCredential.user;
    // ...
  })
  .catch((error) => {
    var errorCode = error.code;
    var errorMessage = error.message;
    // ...
  });

Web version 9

import { getAuth, signInWithCustomToken } from "firebase/auth";

const auth = getAuth();
signInWithCustomToken(auth, token)
  .then((userCredential) => {
    // Signed in
    const user = userCredential.user;
    // ...
  })
  .catch((error) => {
    const errorCode = error.code;
    const errorMessage = error.message;
    // ...
  });

Nếu xác thực thành công, người dùng của bạn sẽ được đăng nhập vào ứng dụng khách của bạn bằng tài khoản được chỉ định bởi uid có trong mã thông báo tùy chỉnh. Nếu tài khoản đó không tồn tại trước đó, một bản ghi cho người dùng đó sẽ được tạo.

Theo cách tương tự như với các phương thức đăng nhập khác (chẳng hạn như signInWithEmailAndPassword()signInWithCredential() ), đối tượng auth trong Quy tắc cơ sở dữ liệu thời gian thực của bạn và đối tượng request.auth trong Quy tắc bảo mật lưu trữ đám mây của bạn sẽ được điền bằng uid của người dùng. Trong trường hợp này, uid sẽ là uid mà bạn đã chỉ định khi tạo mã thông báo tùy chỉnh.

Quy tắc cơ sở dữ liệu

{
  "rules": {
    "adminContent": {
      ".read": "auth.uid === 'some-uid'"
    }
  }
}

Quy tắc lưu trữ

service firebase.storage {
  match /b/<your-firebase-storage-bucket>/o {
    match /adminContent/{filename} {
      allow read, write: if request.auth != null && request.auth.uid == "some-uid";
    }
  }
}

Nếu mã thông báo tùy chỉnh chứa các xác nhận quyền sở hữu bổ sung, chúng có thể được tham chiếu ngoài đối tượng auth.token (Cơ sở dữ liệu thời gian thực của Firebase) hoặc request.auth.token (Bộ nhớ đám mây) trong quy tắc của bạn:

Quy tắc cơ sở dữ liệu

{
  "rules": {
    "premiumContent": {
      ".read": "auth.token.premiumAccount === true"
    }
  }
}

Quy tắc lưu trữ

service firebase.storage {
  match /b/<your-firebase-storage-bucket>/o {
    match /premiumContent/{filename} {
      allow read, write: if request.auth.token.premiumAccount == true;
    }
  }
}

Tạo mã thông báo tùy chỉnh bằng thư viện JWT của bên thứ ba

Nếu chương trình phụ trợ của bạn ở ngôn ngữ không có SDK quản trị Firebase chính thức, thì bạn vẫn có thể tạo mã thông báo tùy chỉnh theo cách thủ công. Trước tiên, hãy tìm thư viện JWT của bên thứ ba cho ngôn ngữ của bạn. Sau đó, sử dụng thư viện JWT đó để đúc JWT bao gồm các yêu cầu sau:

Yêu cầu mã thông báo tùy chỉnh
alg thuật toán "RS256"
iss Tổ chức phát hành Địa chỉ email tài khoản dịch vụ dự án của bạn
sub Môn học Địa chỉ email tài khoản dịch vụ dự án của bạn
aud Khán giả "https://identitytoolkit.googleapis.com/google.identity.identitytoolkit.v1.IdentityToolkit"
iat Ban hành tại thời điểm Thời gian hiện tại, tính bằng giây kể từ kỷ nguyên UNIX
exp thời gian hết hạn Thời gian, tính bằng giây kể từ kỷ nguyên UNIX, tại đó mã thông báo hết hạn. Nó có thể muộn hơn tối đa 3600 giây so với iat .
Lưu ý: điều này chỉ kiểm soát thời gian khi mã thông báo tùy chỉnh hết hạn. Nhưng sau khi bạn đăng nhập người dùng bằng signInWithCustomToken() , họ sẽ vẫn đăng nhập vào thiết bị cho đến khi phiên của họ bị vô hiệu hoặc người dùng đăng xuất.
uid Mã định danh duy nhất của người dùng đã đăng nhập phải là một chuỗi, bao gồm cả độ dài từ 1-128 ký tự. uid s ngắn hơn cung cấp hiệu suất tốt hơn.
claims (tùy chọn) Các yêu cầu tùy chỉnh tùy chọn để đưa vào các biến auth / request.auth của Quy tắc bảo mật

Dưới đây là một số triển khai ví dụ về cách tạo mã thông báo tùy chỉnh bằng nhiều ngôn ngữ mà SDK quản trị Firebase không hỗ trợ:

PHP

Sử dụng php-jwt :

// Requires: composer require firebase/php-jwt
use Firebase\JWT\JWT;

// Get your service account's email address and private key from the JSON key file
$service_account_email = "abc-123@a-b-c-123.iam.gserviceaccount.com";
$private_key = "-----BEGIN PRIVATE KEY-----...";

function create_custom_token($uid, $is_premium_account) {
  global $service_account_email, $private_key;

  $now_seconds = time();
  $payload = array(
    "iss" => $service_account_email,
    "sub" => $service_account_email,
    "aud" => "https://identitytoolkit.googleapis.com/google.identity.identitytoolkit.v1.IdentityToolkit",
    "iat" => $now_seconds,
    "exp" => $now_seconds+(60*60),  // Maximum expiration time is one hour
    "uid" => $uid,
    "claims" => array(
      "premium_account" => $is_premium_account
    )
  );
  return JWT::encode($payload, $private_key, "RS256");
}

hồng ngọc

Sử dụng ruby-jwt :

require "jwt"

# Get your service account's email address and private key from the JSON key file
$service_account_email = "service-account@my-project-abc123.iam.gserviceaccount.com"
$private_key = OpenSSL::PKey::RSA.new "-----BEGIN PRIVATE KEY-----\n..."

def create_custom_token(uid, is_premium_account)
  now_seconds = Time.now.to_i
  payload = {:iss => $service_account_email,
             :sub => $service_account_email,
             :aud => "https://identitytoolkit.googleapis.com/google.identity.identitytoolkit.v1.IdentityToolkit",
             :iat => now_seconds,
             :exp => now_seconds+(60*60), # Maximum expiration time is one hour
             :uid => uid,
             :claims => {:premium_account => is_premium_account}}
  JWT.encode payload, $private_key, "RS256"
end

Sau khi bạn tạo mã thông báo tùy chỉnh, hãy gửi mã đó đến ứng dụng khách của bạn để sử dụng xác thực với Firebase. Xem các mẫu mã ở trên để biết cách thực hiện việc này.

Xử lý sự cố

Phần này phác thảo một số vấn đề phổ biến mà nhà phát triển có thể gặp phải khi tạo mã thông báo tùy chỉnh và cách giải quyết chúng.

API IAM chưa được bật

Nếu bạn đang chỉ định ID tài khoản dịch vụ để ký mã thông báo, bạn có thể gặp lỗi tương tự như sau:

Identity and Access Management (IAM) API has not been used in project
1234567890 before or it is disabled. Enable it by visiting
https://console.developers.google.com/apis/api/iam.googleapis.com/overview?project=1234567890
then retry. If you enabled this API recently, wait a few minutes for the action
to propagate to our systems and retry.

SDK quản trị Firebase sử dụng API IAM để ký mã thông báo. Lỗi này cho biết rằng API IAM hiện không được bật cho dự án Firebase của bạn. Mở liên kết trong thông báo lỗi trong trình duyệt web và nhấp vào nút "Bật API" để bật nó cho dự án của bạn.

Tài khoản dịch vụ không có quyền cần thiết

Nếu tài khoản dịch vụ mà SDK quản trị Firebase đang chạy không có quyền iam.serviceAccounts.signBlob , thì bạn có thể nhận được thông báo lỗi như sau:

Permission iam.serviceAccounts.signBlob is required to perform this operation
on service account projects/-/serviceAccounts/{your-service-account-id}.

Cách dễ nhất để giải quyết vấn đề này là cấp vai trò IAM "Trình tạo mã thông báo tài khoản dịch vụ" cho tài khoản dịch vụ được đề cập, thường là {project-name}@appspot.gserviceaccount.com :

  1. Mở IAM và trang quản trị trong Google Cloud Console.
  2. Chọn dự án của bạn và nhấp vào "Tiếp tục".
  3. Nhấp vào biểu tượng chỉnh sửa tương ứng với tài khoản dịch vụ bạn muốn cập nhật.
  4. Nhấp vào "Thêm vai trò khác".
  5. Nhập "Trình tạo mã thông báo tài khoản dịch vụ" vào bộ lọc tìm kiếm và chọn nó từ kết quả.
  6. Nhấp vào "Lưu" để xác nhận cấp vai trò.

Tham khảo tài liệu IAM để biết thêm chi tiết về quy trình này hoặc tìm hiểu cách thực hiện cập nhật vai trò bằng công cụ dòng lệnh gcloud.

Không thể xác định tài khoản dịch vụ

Nếu bạn nhận được thông báo lỗi tương tự như sau, SDK quản trị Firebase chưa được khởi tạo đúng cách.

Failed to determine service account ID. Initialize the SDK with service account
credentials or specify a service account ID with iam.serviceAccounts.signBlob
permission.

Nếu bạn đang dựa vào SDK để tự động phát hiện ID tài khoản dịch vụ, hãy đảm bảo mã được triển khai trong môi trường Google được quản lý với máy chủ siêu dữ liệu. Nếu không, hãy nhớ chỉ định tệp JSON của tài khoản dịch vụ hoặc ID tài khoản dịch vụ khi khởi tạo SDK.