אישור בקשות שליחה

בקשות שנשלחות אל FCM משרת האפליקציה או מהסביבה המהימנה חייבות לקבל הרשאה. שימו לב להבדלים החשובים הבאים בין גרסאות API מדור קודם ל-HTTP API ולהרשאות HTTP v1 API:

  • ה-API HTTP v1 של FCM מאשר בקשות עם אסימון גישה לטווח קצר מסוג OAuth 2.0. כדי ליצור את האסימון הזה, אפשר להשתמש ב-Application Default Credentials של Google (בסביבות שרת של Google) ו/או לקבל באופן ידני את פרטי הכניסה הנדרשים מקובץ מפתח פרטי בפורמט JSON שנוצר לחשבון שירות. אם משתמשים בFirebase Admin SDK כדי לשלוח הודעות, הספרייה מטפלת באסימון בשבילכם.
  • בפרוטוקולים מדור קודם שהוצאו משימוש אפשר להשתמש רק במפתחות API לטווח ארוך שהתקבלו מהמסוף Firebase.

אישור בקשות שליחה של HTTP v1

בהתאם לפרטים של סביבת השרת, אפשר להשתמש בשילוב של אסטרטגיות האלה כדי לאשר בקשות מהשרת לשירותי Firebase:

  • Google Application Default Credentials‏ (ADC)
  • קובץ JSON של חשבון שירות
  • אסימון גישה לטווח קצר מסוג OAuth 2.0 שמבוסס על חשבון שירות

אם האפליקציה שלכם פועלת ב-Compute Engine,‏ Google Kubernetes Engine,‏ App Engine או ב-Cloud Functions (כולל Cloud Functions for Firebase), השתמשו ב-Application Default Credentials ‏(ADC). מערכת ADC משתמשת בחשבון השירות המוגדר כברירת מחדל כדי לקבל פרטי כניסה להרשאת בקשות, והיא מאפשרת בדיקה מקומית גמישה באמצעות משתנה הסביבה GOOGLE_APPLICATION_CREDENTIALS. כדי לבצע אוטומציה מלאה של תהליך ההרשאה, צריך להשתמש ב-ADC יחד עם ספריות השרת של Admin SDK.

אם האפליקציה פועלת בסביבת שרת שאינה של Google, תצטרכו להוריד קובץ JSON של חשבון שירות מהפרויקט ב-Firebase. כל עוד יש לכם גישה למערכת קבצים שמכילה את קובץ המפתח הפרטי, תוכלו להשתמש במשתנה הסביבה GOOGLE_APPLICATION_CREDENTIALS כדי לאשר בקשות באמצעות פרטי הכניסה האלה שהתקבלו באופן ידני. אם אין לכם גישה לקובץ כזה, עליכם להפנות לקובץ של חשבון השירות בקוד – וצריך לעשות זאת בזהירות רבה בגלל הסיכון לחשיפת פרטי הכניסה שלכם.

מסירת פרטי הכניסה באמצעות ADC

Google Application Default Credentials (ADC) בודק את פרטי הכניסה שלכם. בסדר הבא:

  1. ADC בודק אם משתנה הסביבה GOOGLE_APPLICATION_CREDENTIALS מוגדרת. אם המשתנה מוגדר, ADC משתמש בקובץ חשבון השירות שאליו מצביע המשתנה.

  2. אם משתנה הסביבה לא מוגדר, חיפוש פרטי הכניסה ב-ADC מתבצע באמצעות חשבון השירות שמוגדר כברירת מחדל ב-Compute Engine, ב-Google Kubernetes Engine, ב-App Engine וב-Cloud Functions לאפליקציות שפועלות בשירותים האלה.

  3. אם ADC לא מצליח להשתמש בפרטי הכניסה שצוינו למעלה, המערכת תגרור הודעת שגיאה.

דוגמת הקוד הבאה של Admin SDK ממחישה את האסטרטגיה הזו. הדוגמה לא מציין במפורש את פרטי הכניסה של האפליקציה. עם זאת, ADC יכול למצוא את פרטי הכניסה באופן משתמע כל עוד משתנה הסביבה מוגדר, או כל עוד האפליקציה פועלת ב-Compute Engine, ב-Google Kubernetes Engine, ב-App Engine או ב-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()

Go

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(),
});

הזנה ידנית של פרטי הכניסה

פרויקטים ב-Firebase תומכים בחשבונות שירות של Google, שבאמצעותם אפשר לבצע קריאה ל-API של שרת Firebase משרת האפליקציה או מסביבה מהימנה. אם אתם מפתחים באופן מקומי או בפריסה של האפליקציה בארגון, תוכלו להשתמש בפרטי הכניסה שקיבלתם באמצעות חשבון השירות הזה כדי לאשר בקשות שרת.

כדי לאמת חשבון שירות ולהעניק לו הרשאת גישה לשירותי Firebase, צריך ליצור קובץ מפתח פרטי בפורמט JSON.

כדי ליצור קובץ מפתח פרטי לחשבון השירות:

  1. במסוף Firebase, פותחים את Settings (הגדרות) > Service Accounts (חשבונות שירות).

  2. לוחצים על Generate New Private Key (יצירת מפתח פרטי חדש) ולאחר מכן לוחצים על Generate Key (יצירת מפתח) כדי לאשר.

  3. שומרים באופן מאובטח את קובץ ה-JSON שמכיל את המפתח.

כשאתם נותנים הרשאה דרך חשבון שירות, יש לכם שתי אפשרויות למסור את פרטי הכניסה לאפליקציה. אפשר להגדיר משתנה סביבה אחד (GOOGLE_APPLICATION_CREDENTIALS), או שאפשר להעביר באופן מפורש את הנתיב למפתח של חשבון השירות בקוד. האפשרות הראשונה מאובטחת יותר ומומלצת מאוד.

כדי להגדיר את משתנה הסביבה:

מגדירים את משתנה הסביבה GOOGLE_APPLICATION_CREDENTIALS לנתיב של קובץ ה-JSON שמכיל את המַפְתח של חשבון השירות. המשתנה הזה חל רק על סשן המעטפת הנוכחי, כך שאם פותחים סשן חדש צריך להגדיר את המשתנה שוב.

Linux או macOS

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

Windows

באמצעות PowerShell:

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

אחרי שתסיימו את השלבים שלמעלה, תצטרכו להשתמש ב-Application Default Credentials (ADC). מסוגל לקבוע במרומז את פרטי הכניסה שלכם, ולאפשר לכם להשתמש בשירות של החשבון בזמן בדיקה או הפעלה בסביבות שאינן של Google.

שימוש בפרטי כניסה כדי ליצור אסימוני גישה

אם לא משתמשים Admin SDK, כדי לטפל בהרשאה באופן אוטומטי, תצטרכו להנפיק אסימון גישה ומוסיפים אותו כדי לשלוח בקשות.

משתמשים בפרטי הכניסה ל-Firebase בשילוב עם ספריית Google Auth לשפה המועדפת עליך כדי לאחזר אסימון גישה לטווח קצר מסוג OAuth 2.0:

node.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);
    });
  });
}

בדוגמה הזו, ספריית הלקוח של Google API מאמתת את הבקשה באמצעות אסימון אינטרנט מסוג JSON‏ (JWT). למידע נוסף, ראו אסימוני אינטרנט מסוג 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();
}

אחרי שתוקף אסימון הגישה יפוג, השיטה לרענון האסימון תופעל באופן אוטומטי כדי לאחזר אסימון גישה מעודכן.

כדי לתת הרשאת גישה ל-FCM, צריך לבקש את ההיקף https://www.googleapis.com/auth/firebase.messaging.

כדי להוסיף את אסימון הגישה לכותרת של בקשת HTTP:

מוסיפים את האסימון כערך של הכותרת Authorization בפורמט Authorization: Bearer <access_token>:

node.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;

מתן הרשאה לבקשות שליחה של פרוטוקולים מדור קודם

בפרוטוקול HTTP הקודם, כל בקשה חייבת לכלול את מפתח השרת מהכרטיסייה Cloud Messaging בחלונית Settings במסוף Firebase. ב-XMPP, צריך להשתמש באותו מפתח שרת כדי ליצור חיבור.

העברת מפתחות שרת מדור קודם

החל ממרץ 2020, FCM הפסיק ליצור מפתחות שרת מדור קודם. מפתחות השרת הקודמים ימשיכו לפעול, אבל מומלץ להשתמש במקום זאת בגרסת המפתח החדשה יותר שמסומנת בתווית מפתח שרת במסוף Firebase.

אם רוצים למחוק מפתח שרת קיים מדור קודם, אפשר לעשות זאת מסוף Google Cloud.

הרשאה לבקשות HTTP

בקשת הודעה מורכבת משני חלקים: כותרת ה-HTTP וגוף ה-HTTP. כותרת ה-HTTP חייבת לכלול את הכותרות הבאות:

  • Authorization: key=YOUR_שמה_KEY
    יש לוודא שזה מפתח השרת, שהערך שלו הוא זמינה ב הכרטיסייה 'העברת הודעות בענן' בחלונית הגדרות במסוף Firebase. מפתחות של Android, פלטפורמת Apple ומפתחות דפדפן נדחים על ידי FCM.
  • Content-Type: application/json ל-JSON,‏ application/x-www-form-urlencoded;charset=UTF-8 לטקסט פשוט.
    אם לא משמיטים את Content-Type, הפורמט נחשבת כטקסט פשוט.

לדוגמה:

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

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

ראו יצירת בקשות לשליחה לקבלת פרטים מלאים על יצירת בקשות שליחה. חומר העזר על פרוטוקול HTTP מדור קודם מספקת רשימה של כל הפרמטרים שההודעה שלכם יכולה להכיל.

בדיקת התוקף של מפתח שרת

אם מתקבלות שגיאות אימות כששולחים הודעות, יש לבדוק את התקינות של מפתח השרת שלכם. לדוגמה, ב-Linux, מריצים את הפקודה הבאה:

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\"]}"

אם קיבלתם קוד מצב 401 HTTP, מפתח השרת שלכם לא חוקי.

אישור של חיבור XMPP

עם XMPP, אפשר חיבור קבוע ואסינכרוני, דו-כיווני לשרתים של FCM. יכול לשמש לשליחה ולקבלה של הודעות בין השרת שלך לבין של המשתמשים שלך FCM מכשירים מחוברים.

אפשר להשתמש ברוב ספריות ה-XMPP כדי לנהל חיבור לטווח ארוך ל-FCM. נקודת הקצה של XMPP פועלת ב-fcm-xmpp.googleapis.com:5235. כשבודקים את הפונקציונליות עם משתמשים שאינם בסביבת הייצור, צריך להתחבר לשרת של סביבות טרום-ייצור בכתובת fcm-xmpp.googleapis.com:5236 (שימו לב לשינוי ביציאה).

בדיקה רגילה בשלב טרום-ייצור (סביבה קטנה יותר שבה גרסאות ה-build האחרונות של FCM) הן שימושי לבידוד משתמשים אמיתיים מקוד בדיקה. במכשירי בדיקה ובקוד בדיקה שמתחברים אל fcm-xmpp.googleapis.com:5236 צריך להשתמש במזהה שולח FCM שונה כדי למנוע סיכונים של שליחת הודעות בדיקה למשתמשים בסביבת הייצור או שליחת הודעות מ-upstream מתעבורת נתונים בסביבת הייצור דרך חיבורי בדיקה.

יש לחיבור שתי דרישות חשובות:

  • עליכם להתחיל חיבור של Transport Layer Security (TLS). לתשומת ליבכם: FCM לא תומך כרגע בתוסף STARTTLS.
  • ל-FCM נדרש מנגנון אימות SASL PLAIN באמצעות <your_FCM_Sender_Id>@fcm.googleapis.com (מזהה שולח של FCM) ואת מקש השרת בתור הסיסמה. הערכים האלה הם זמינה ב הכרטיסייה 'העברת הודעות בענן' בחלונית הגדרות במסוף Firebase.

אם בשלב כלשהו החיבור נכשל, צריך להתחבר מחדש באופן מיידי. אין צורך לבצע נסיגה אחרי ניתוק שמתרחש אחרי האימות. לכל מזהה שולח, FCM מאפשר 2,500 חיבורים במקביל.

קטעי הקוד הבאים ממחישים איך לבצע אימות הרשאה לחיבור XMPP אל FCM.

שרת XMPP

שרת ה-XMPP מבקש חיבור אל FCM

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

FCM

FCM פותח את החיבור ומבקש מנגנון אימות, כולל 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>

שרת XMPP

שרת ה-XMPP צריך להשיב באמצעות שיטת האימות PLAIN, ולספק את מפתח השרת מהכרטיסייה Cloud Messaging בחלונית Settings במסוף 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"/>

שרת 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>

שרת 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>

הערה: FCM לא משתמש במשאב המקושר בזמן ניתוב הודעות.

ראו יצירת בקשות לשליחה לקבלת פרטים מלאים על יצירת בקשות שליחה. חומר העזר בנושא פרוטוקול XMPP מדור קודם מספקת רשימה של כל הפרמטרים שההודעה שלכם יכולה להכיל.