Cho phép gửi yêu cầu

Yêu cầu gửi tới FCM từ máy chủ ứng dụng hoặc môi trường đáng tin cậy của bạn phải được ủy quyền. Lưu ý những khác biệt quan trọng này giữa ủy quyền API HTTP cũ và ủy quyền API HTTP v1 không được dùng nữa:

  • API FCM HTTP v1 cho phép các yêu cầu bằng mã thông báo truy cập OAuth 2.0 tồn tại trong thời gian ngắn. Để tạo ra mã thông báo này, bạn có thể sử dụng Thông tin xác thực mặc định của ứng dụng Google (trong môi trường máy chủ Google) và/hoặc lấy thông tin xác thực cần thiết theo cách thủ công từ tệp khóa riêng JSON được tạo cho tài khoản dịch vụ. Nếu bạn đang sử dụng SDK quản trị Firebase để gửi tin nhắn thì thư viện sẽ xử lý mã thông báo cho bạn.
  • Các giao thức cũ không còn được dùng nữa chỉ có thể sử dụng các khóa API tồn tại lâu dài thu được từ bảng điều khiển Firebase.

Cho phép gửi yêu cầu HTTP v1

Tùy thuộc vào chi tiết môi trường máy chủ của bạn, hãy sử dụng kết hợp các chiến lược này để ủy quyền các yêu cầu máy chủ tới các dịch vụ Firebase:

  • Thông tin xác thực mặc định của ứng dụng Google (ADC)
  • Tệp JSON của tài khoản dịch vụ
  • Mã thông báo truy cập OAuth 2.0 tồn tại trong thời gian ngắn được lấy từ tài khoản dịch vụ

Nếu ứng dụng của bạn đang chạy trên Computing Engine, Google Kubernetes Engine, App Engine hoặc Cloud Functions (bao gồm Cloud Functions cho Firebase), hãy sử dụng Thông tin xác thực mặc định của ứng dụng (ADC). ADC sử dụng tài khoản dịch vụ mặc định hiện có của bạn để lấy thông tin xác thực nhằm cho phép các yêu cầu và ADC cho phép thử nghiệm cục bộ linh hoạt thông qua biến môi trường GOOGLE_APPLICATION_CREDENTIALS . Để tự động hóa luồng ủy quyền tối đa, hãy sử dụng ADC cùng với các thư viện máy chủ SDK dành cho quản trị viên.

Nếu ứng dụng của bạn đang chạy trên môi trường máy chủ không phải của Google , bạn sẽ cần tải xuống tệp JSON của tài khoản dịch vụ từ dự án Firebase của mình. Miễn là bạn có quyền truy cập vào hệ thống tệp chứa tệp khóa riêng tư, bạn có thể sử dụng biến môi trường GOOGLE_APPLICATION_CREDENTIALS để ủy quyền các yêu cầu có thông tin xác thực được lấy theo cách thủ công này. Nếu bạn không có quyền truy cập vào tệp như vậy, bạn phải tham chiếu tệp tài khoản dịch vụ trong mã của mình— việc này phải được thực hiện hết sức thận trọng do có nguy cơ làm lộ thông tin xác thực của bạn.

Cung cấp thông tin xác thực bằng ADC

Thông tin xác thực mặc định của ứng dụng Google (ADC) kiểm tra thông tin xác thực của bạn theo thứ tự sau:

  1. ADC kiểm tra xem biến môi trường GOOGLE_APPLICATION_CREDENTIALS có được đặt hay không. Nếu biến được đặt, ADC sẽ sử dụng tệp tài khoản dịch vụ mà biến đó trỏ đến.

  2. Nếu biến môi trường không được đặt, ADC sẽ sử dụng tài khoản dịch vụ mặc định mà Computing Engine, Google Kubernetes Engine, App Engine và Cloud Functions cung cấp cho các ứng dụng chạy trên các dịch vụ đó.

  3. Nếu ADC không thể sử dụng một trong các thông tin xác thực trên thì hệ thống sẽ báo lỗi.

Ví dụ về mã SDK quản trị sau đây minh họa chiến lược này. Ví dụ này không chỉ định rõ ràng thông tin đăng nhập của ứng dụng. Tuy nhiên, ADC có thể ngầm tìm thấy thông tin xác thực miễn là biến môi trường được đặt hoặc miễn là ứng dụng đang chạy trên Computing Engine, Google Kubernetes Engine, App Engine hoặc Cloud Functions.

Node.js

admin.initializeApp({
  credential: admin.credential.applicationDefault(),
});

Java

FirebaseOptions options = FirebaseOptions.builder()
    .setCredentials(GoogleCredentials.getApplicationDefault())
    .setDatabaseUrl("https://<DATABASE_NAME>.firebaseio.com/")
    .build();

FirebaseApp.initializeApp(options);

Python

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(new AppOptions()
{
    Credential = GoogleCredential.GetApplicationDefault(),
});

Cung cấp thông tin đăng nhập theo cách thủ công

Các dự án Firebase hỗ trợ các tài khoản dịch vụ của Google mà bạn có thể sử dụng để gọi API máy chủ Firebase từ máy chủ ứng dụng hoặc môi trường đáng tin cậy của mình. Nếu bạn đang phát triển mã cục bộ hoặc triển khai ứng dụng của mình tại chỗ, bạn có thể sử dụng thông tin xác thực có được thông qua tài khoản dịch vụ này để ủy quyền các yêu cầu máy chủ.

Để xác thực tài khoản dịch vụ và ủy quyền cho tài khoản đó truy cập các dịch vụ Firebase, bạn phải tạo tệp khóa riêng ở định dạng JSON.

Để tạo tệp khóa riêng cho tài khoản dịch vụ của bạn:

  1. Trong bảng điều khiển Firebase, hãy mở Cài đặt > Tài khoản dịch vụ .

  2. Nhấp vào Tạo khóa riêng mới , sau đó xác nhận bằng cách nhấp vào Tạo khóa .

  3. Lưu trữ an toàn tệp JSON chứa khóa.

Khi ủy quyền thông qua tài khoản dịch vụ, bạn có hai lựa chọn để cung cấp thông tin xác thực cho ứng dụng của mình. Bạn có thể đặt biến môi trường GOOGLE_APPLICATION_CREDENTIALS hoặc bạn có thể chuyển đường dẫn đến khóa tài khoản dịch vụ một cách rõ ràng trong mã. Tùy chọn đầu tiên an toàn hơn và được khuyến khích sử dụng.

Để đặt biến môi trường:

Đặt biến môi trường GOOGLE_APPLICATION_CREDENTIALS thành đường dẫn tệp của tệp JSON chứa khóa tài khoản dịch vụ của bạn. Biến này chỉ áp dụng cho phiên shell hiện tại của bạn, vì vậy nếu bạn mở một phiên mới, hãy đặt lại biến.

Linux hoặc macOS

export GOOGLE_APPLICATION_CREDENTIALS="/home/user/Downloads/service-account-file.json"

các cửa sổ

Với PowerShell:

$env:GOOGLE_APPLICATION_CREDENTIALS="C:\Users\username\Downloads\service-account-file.json"

Sau khi bạn hoàn thành các bước trên, Thông tin xác thực mặc định của ứng dụng (ADC) có thể ngầm xác định thông tin xác thực của bạn, cho phép bạn sử dụng thông tin xác thực tài khoản dịch vụ khi thử nghiệm hoặc chạy trong môi trường không phải của Google.

Sử dụng thông tin xác thực để đúc mã thông báo truy cập

Trừ khi bạn đang sử dụng SDK quản trị để tự động xử lý ủy quyền, bạn sẽ cần tạo mã thông báo truy cập và thêm nó để gửi yêu cầu.

Sử dụng thông tin xác thực Firebase của bạn cùng với Thư viện Google Auth cho ngôn ngữ ưa thích của bạn để truy xuất mã thông báo truy cập OAuth 2.0 tồn tại trong thời gian ngắn:

nút.js

 function getAccessToken() {
  return new Promise(function(resolve, reject) {
    const key = require('../placeholders/service-account.json');
    const jwtClient = new google.auth.JWT(
      key.client_email,
      null,
      key.private_key,
      SCOPES,
      null
    );
    jwtClient.authorize(function(err, tokens) {
      if (err) {
        reject(err);
        return;
      }
      resolve(tokens.access_token);
    });
  });
}

Trong ví dụ này, thư viện ứng dụng khách Google API xác thực yêu cầu bằng mã thông báo web JSON hoặc JWT. Để biết thêm thông tin, hãy xem Mã thông báo web JSON .

Python

def _get_access_token():
  """Retrieve a valid access token that can be used to authorize requests.

  :return: Access token.
  """
  credentials = service_account.Credentials.from_service_account_file(
    'service-account.json', scopes=SCOPES)
  request = google.auth.transport.requests.Request()
  credentials.refresh(request)
  return credentials.token

Java

private static String getAccessToken() throws IOException {
  GoogleCredentials googleCredentials = GoogleCredentials
          .fromStream(new FileInputStream("service-account.json"))
          .createScoped(Arrays.asList(SCOPES));
  googleCredentials.refresh();
  return googleCredentials.getAccessToken().getTokenValue();
}

Sau khi mã thông báo truy cập của bạn hết hạn, phương thức làm mới mã thông báo sẽ được gọi tự động để truy xuất mã thông báo truy cập đã cập nhật.

Để cấp quyền truy cập vào FCM, hãy yêu cầu phạm vi https://www.googleapis.com/auth/firebase.messaging .

Để thêm mã thông báo truy cập vào tiêu đề yêu cầu HTTP:

Thêm mã thông báo làm giá trị của tiêu đề Authorization ở định dạng Authorization: Bearer <access_token> :

nút.js

headers: {
  'Authorization': 'Bearer ' + accessToken
}

Python

headers = {
  'Authorization': 'Bearer ' + _get_access_token(),
  'Content-Type': 'application/json; UTF-8',
}

Java

URL url = new URL(BASE_URL + FCM_SEND_ENDPOINT);
HttpURLConnection httpURLConnection = (HttpURLConnection) url.openConnection();
httpURLConnection.setRequestProperty("Authorization", "Bearer " + getServiceAccountAccessToken());
httpURLConnection.setRequestProperty("Content-Type", "application/json; UTF-8");
return httpURLConnection;

Cho phép gửi yêu cầu giao thức kế thừa

Với giao thức cũ HTTP, mỗi yêu cầu phải chứa khóa máy chủ từ tab Nhắn tin qua đám mây của ngăn Cài đặt bảng điều khiển Firebase. Đối với XMPP, bạn phải sử dụng cùng một khóa máy chủ để thiết lập kết nối.

Di chuyển khóa máy chủ cũ

Bắt đầu từ tháng 3 năm 2020, FCM đã ngừng tạo khóa máy chủ cũ. Các khóa máy chủ cũ hiện tại sẽ tiếp tục hoạt động nhưng thay vào đó, chúng tôi khuyên bạn nên sử dụng phiên bản mới hơn của khóa có nhãn Khóa máy chủ trong bảng điều khiển Firebase .

Nếu muốn xóa khóa máy chủ cũ hiện có, bạn có thể thực hiện việc đó trong bảng điều khiển Google Cloud .

Cho phép các yêu cầu HTTP

Một yêu cầu tin nhắn bao gồm hai phần: tiêu đề HTTP và nội dung HTTP. Tiêu đề HTTP phải chứa các tiêu đề sau:

  • Authorization : key=YOUR_SERVER_KEY
    Đảm bảo đây là khóa máy chủ , có giá trị có sẵn trong tab Nhắn tin qua đám mây của ngăn Cài đặt bảng điều khiển Firebase. Nền tảng Android, Apple và khóa trình duyệt bị FCM từ chối.
  • Content-Type : application/json cho JSON; application/x-www-form-urlencoded;charset=UTF-8 cho văn bản thuần túy.
    Nếu Content-Type bị bỏ qua, định dạng được coi là văn bản thuần túy.

Ví dụ:

Content-Type:application/json
Authorization:key=AIzaSyZ-1u...0GBYzPu7Udno5aA

{
  "to" : "bk3RNwTe3H0:CI2k_HHwgIpoDKCIZvvDMExUdFQ3P1...",
  "data" : {
    ...
  },
}

Xem Xây dựng yêu cầu gửi để biết chi tiết đầy đủ về cách tạo yêu cầu gửi. Tham chiếu Giao thức HTTP kế thừa cung cấp danh sách tất cả các tham số mà tin nhắn của bạn có thể chứa.

Kiểm tra tính hợp lệ của khóa máy chủ

Nếu bạn nhận được lỗi xác thực khi gửi tin nhắn, hãy kiểm tra tính hợp lệ của khóa Máy chủ của bạn. Ví dụ: trên Linux, hãy chạy lệnh sau:

api_key=YOUR_SERVER_KEY

curl --header "Authorization: key=$api_key" \
     --header Content-Type:"application/json" \
     https://fcm.googleapis.com/fcm/send \
     -d "{\"registration_ids\":[\"ABC\"]}"

Nếu bạn nhận được mã trạng thái HTTP 401 thì khóa Máy chủ của bạn không hợp lệ.

Cho phép kết nối XMPP

Với XMPP, bạn có thể duy trì kết nối hai chiều, không đồng bộ, liên tục với máy chủ FCM. Kết nối có thể được sử dụng để gửi và nhận tin nhắn giữa máy chủ của bạn và thiết bị được kết nối FCM của người dùng.

Bạn có thể sử dụng hầu hết các thư viện XMPP để quản lý kết nối lâu dài với FCM. Điểm cuối XMPP chạy tại fcm-xmpp.googleapis.com:5235 . Khi thử nghiệm chức năng với người dùng không phải là người dùng chính thức, thay vào đó, bạn nên kết nối với máy chủ tiền sản xuất tại fcm-xmpp.googleapis.com:5236 (lưu ý cổng khác).

Thử nghiệm thường xuyên trong quá trình tiền sản xuất (một môi trường nhỏ hơn nơi chạy các bản dựng FCM mới nhất) có lợi cho việc tách biệt người dùng thực khỏi mã thử nghiệm. Thiết bị thử nghiệm và mã thử nghiệm kết nối với fcm-xmpp.googleapis.com:5236 phải sử dụng ID người gửi FCM khác để tránh mọi rủi ro khi gửi tin nhắn thử nghiệm cho người dùng sản xuất hoặc gửi tin nhắn ngược dòng từ lưu lượng truy cập sản xuất qua kết nối thử nghiệm.

Kết nối có hai yêu cầu quan trọng:

  • Bạn phải bắt đầu kết nối Bảo mật lớp vận chuyển (TLS). Lưu ý rằng FCM hiện không hỗ trợ tiện ích mở rộng STARTTLS .
  • FCM yêu cầu cơ chế xác thực SASL PLAIN bằng cách sử dụng <your_FCM_Sender_Id>@fcm.googleapis.com ( ID người gửi FCM ) và Khóa máy chủ làm mật khẩu. Các giá trị này có sẵn trong tab Nhắn tin qua đám mây của ngăn Cài đặt bảng điều khiển Firebase.

Nếu tại bất kỳ thời điểm nào kết nối không thành công, bạn nên kết nối lại ngay lập tức. Không cần phải dừng lại sau khi ngắt kết nối xảy ra sau khi xác thực. Đối với mỗi ID người gửi , FCM cho phép 2500 kết nối song song.

Đoạn mã sau minh họa cách thực hiện xác thực và ủy quyền cho kết nối XMPP tới FCM.

máy chủ XMPP

Máy chủ XMPP yêu cầu kết nối tới FCM

<stream:stream to="fcm.googleapis.com"
        version="1.0" xmlns="jabber:client"
        xmlns:stream="http://etherx.jabber.org/streams">

FCM

FCM mở kết nối và yêu cầu cơ chế xác thực, bao gồm cả phương thức PLAIN .

<stream:features>
  <mechanisms xmlns="urn:ietf:params:xml:ns:xmpp-sasl">
    <mechanism>X-OAUTH2</mechanism>
    <mechanism>X-GOOGLE-TOKEN</mechanism>
    <mechanism>PLAIN</mechanism>
  </mechanisms>
</stream:features>

máy chủ XMPP

Máy chủ XMPP phải phản hồi bằng phương thức xác thực PLAIN , cung cấp khóa máy chủ từ tab Nhắn tin qua đám mây của ngăn Cài đặt bảng điều khiển Firebase.

<auth mechanism="PLAIN"
xmlns="urn:ietf:params:xml:ns:xmpp-sasl">MTI2MjAwMzQ3OTMzQHByb2plY3RzLmdjbS5hb
mFTeUIzcmNaTmtmbnFLZEZiOW1oekNCaVlwT1JEQTJKV1d0dw==</auth>

FCM

<success xmlns="urn:ietf:params:xml:ns:xmpp-sasl"/>

máy chủ XMPP

<stream:stream to="fcm.googleapis.com"
        version="1.0" xmlns="jabber:client"
        xmlns:stream="http://etherx.jabber.org/streams">

FCM

<stream:features>
  <bind xmlns="urn:ietf:params:xml:ns:xmpp-bind"/>
  <session xmlns="urn:ietf:params:xml:ns:xmpp-session"/>
</stream:features>

máy chủ XMPP

<iq type="set">
  <bind xmlns="urn:ietf:params:xml:ns:xmpp-bind"></bind>
</iq>

FCM

<iq type="result">
  <bind xmlns="urn:ietf:params:xml:ns:xmpp-bind">
    <jid>SENDER_ID@fcm.googleapis.com/RESOURCE</jid>
  </bind>
</iq>

Lưu ý: FCM không sử dụng tài nguyên bị ràng buộc trong khi định tuyến tin nhắn.

Xem Xây dựng yêu cầu gửi để biết chi tiết đầy đủ về cách tạo yêu cầu gửi. Tham chiếu Giao thức XMPP kế thừa cung cấp danh sách tất cả các tham số mà tin nhắn của bạn có thể chứa.