Запросы, отправляемые в FCM с вашего сервера приложений или доверенной среды, должны быть авторизованы. Обратите внимание на эти важные различия между устаревшей авторизацией HTTP и HTTP v1 API:
- API-интерфейс FCM HTTP v1 авторизует запросы с помощью недолговечного токена доступа OAuth 2.0. Чтобы создать этот токен, вы можете использовать учетные данные приложения Google по умолчанию (в средах серверов Google) и/или вручную получить необходимые учетные данные из файла закрытого ключа JSON, созданного для учетной записи службы. Если вы используете Firebase Admin SDK для отправки сообщений, токен обрабатывается за вас библиотекой.
- Устаревшие протоколы могут использовать только долгоживущие ключи API, полученные из консоли Firebase.
Авторизовать запросы на отправку HTTP v1
В зависимости от особенностей вашей серверной среды используйте комбинацию этих стратегий для авторизации запросов сервера к службам Firebase:
- Учетные данные приложения Google по умолчанию (ADC)
- JSON-файл сервисной учетной записи
- Кратковременный токен доступа OAuth 2.0, полученный из служебной учетной записи.
Если ваше приложение работает на Compute Engine, Google Kubernetes Engine, App Engine или облачных функциях (включая облачные функции для Firebase), используйте учетные данные приложения по умолчанию (ADC). ADC использует существующую учетную запись службы по умолчанию для получения учетных данных для авторизации запросов, а ADC обеспечивает гибкое локальное тестирование с помощью переменной среды GOOGLE_APPLICATION_CREDENTIALS . Для максимально полной автоматизации процесса авторизации используйте ADC вместе с серверными библиотеками Admin SDK.
Если ваше приложение работает в серверной среде, отличной от Google , вам потребуется загрузить JSON-файл сервисного аккаунта из вашего проекта Firebase. Если у вас есть доступ к файловой системе, содержащей файл закрытого ключа, вы можете использовать переменную среды GOOGLE_APPLICATION_CREDENTIALS для авторизации запросов с этими учетными данными, полученными вручную. Если у вас нет доступа к такому файлу, вы должны сослаться на файл учетной записи службы в своем коде, что следует делать с особой осторожностью из-за риска раскрытия ваших учетных данных.
Предоставьте учетные данные с помощью ADC
Учетные данные приложения Google по умолчанию (ADC) проверяют ваши учетные данные в следующем порядке:
ADC проверяет, установлена ли переменная среды GOOGLE_APPLICATION_CREDENTIALS . Если переменная установлена, ADC использует файл учетной записи службы, на который указывает переменная.
Если переменная среды не задана, ADC использует учетную запись службы по умолчанию, которую Compute Engine, Google Kubernetes Engine, App Engine и Cloud Functions предоставляют для приложений, работающих в этих службах.
Если ADC не может использовать ни один из указанных выше учетных данных, система выдает ошибку.
Следующий пример кода Admin SDK иллюстрирует эту стратегию. В примере явно не указаны учетные данные приложения. Однако ADC может неявно находить учетные данные, пока установлена переменная среды или пока приложение работает в Compute Engine, Google Kubernetes Engine, App Engine или Cloud Functions.
Node.js
admin.initializeApp({
credential: admin.credential.applicationDefault(),
});
Джава
FirebaseOptions options = FirebaseOptions.builder()
.setCredentials(GoogleCredentials.getApplicationDefault())
.setDatabaseUrl("https://<DATABASE_NAME>.firebaseio.com/")
.build();
FirebaseApp.initializeApp(options);
Питон
default_app = firebase_admin.initialize_app()
Идти
app, err := firebase.NewApp(context.Background(), nil)
if err != nil {
log.Fatalf("error initializing app: %v\n", err)
}
С#
FirebaseApp.Create(new AppOptions()
{
Credential = GoogleCredential.GetApplicationDefault(),
});
Введите учетные данные вручную
Проекты Firebase поддерживают сервисные аккаунты Google, которые можно использовать для вызова API-интерфейсов сервера Firebase с вашего сервера приложений или доверенной среды. Если вы разрабатываете код локально или развертываете приложение локально, вы можете использовать учетные данные, полученные через эту учетную запись службы, для авторизации запросов к серверу.
Чтобы аутентифицировать учетную запись службы и разрешить ей доступ к службам Firebase, необходимо создать файл закрытого ключа в формате JSON.
Чтобы сгенерировать файл закрытого ключа для вашей учетной записи службы:
В консоли Firebase откройте «Настройки» > «Учетные записи служб» .
Нажмите «Создать новый закрытый ключ» , затем подтвердите, нажав «Создать ключ» .
Надежно сохраните файл JSON, содержащий ключ.
При авторизации через учетную запись службы у вас есть два варианта предоставления учетных данных вашему приложению. Вы можете либо установить переменную среды GOOGLE_APPLICATION_CREDENTIALS , либо явно указать путь к ключу сервисной учетной записи в коде. Первый вариант более безопасен и настоятельно рекомендуется.
Чтобы установить переменную среды:
Задайте для переменной среды GOOGLE_APPLICATION_CREDENTIALS путь к файлу JSON, содержащему ключ вашей учетной записи службы. Эта переменная применяется только к вашему текущему сеансу оболочки, поэтому, если вы открываете новый сеанс, установите переменную снова.
Линукс или макОС
export GOOGLE_APPLICATION_CREDENTIALS="/home/user/Downloads/service-account-file.json"
Окна
С PowerShell:
$env:GOOGLE_APPLICATION_CREDENTIALS="C:\Users\username\Downloads\service-account-file.json"
После того как вы выполнили вышеуказанные шаги, учетные данные приложения по умолчанию (ADC) могут неявно определять ваши учетные данные, что позволяет вам использовать учетные данные служебной учетной записи при тестировании или запуске в средах, отличных от Google.
Используйте учетные данные для создания токенов доступа
Если вы не используете Admin SDK , который обрабатывает авторизацию автоматически, вам нужно создать токен доступа и добавить его для отправки запросов.
Используйте свои учетные данные Firebase вместе с библиотекой Google Auth Library для предпочитаемого языка, чтобы получить недолговечный токен доступа OAuth 2.0:
узел.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 .
Питон
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
Джава
private static String getAccessToken() throws IOException {
GoogleCredentials googleCredentials = GoogleCredentials
.fromStream(new FileInputStream("service-account.json"))
.createScoped(Arrays.asList(SCOPES));
googleCredentials.refreshAccessToken();
return googleCredentials.getAccessToken().getTokenValue();
}
По истечении срока действия маркера доступа автоматически вызывается метод обновления маркера для получения обновленного маркера доступа.
Чтобы авторизовать доступ к FCM, запросите область действия https://www.googleapis.com/auth/firebase.messaging
.
Чтобы добавить токен доступа в заголовок HTTP-запроса:
Добавьте токен в качестве значения заголовка Authorization
в формате Authorization: Bearer <access_token>
:
узел.js
headers: {
'Authorization': 'Bearer ' + accessToken
}
Питон
headers = {
'Authorization': 'Bearer ' + _get_access_token(),
'Content-Type': 'application/json; UTF-8',
}
Джава
URL url = new URL(BASE_URL + FCM_SEND_ENDPOINT);
HttpURLConnection httpURLConnection = (HttpURLConnection) url.openConnection();
httpURLConnection.setRequestProperty("Authorization", "Bearer " + getAccessToken());
httpURLConnection.setRequestProperty("Content-Type", "application/json; UTF-8");
return httpURLConnection;
Авторизовать запросы на отправку устаревшего протокола
При использовании устаревшего протокола HTTP каждый запрос должен содержать ключ сервера на вкладке Cloud Messaging панели настроек консоли Firebase. Для XMPP вы должны использовать тот же ключ сервера для установки соединения.
Перенос устаревших ключей сервера
Начиная с марта 2020 года FCM прекратил создание устаревших серверных ключей. Существующие устаревшие серверные ключи продолжат работать, но вместо этого мы рекомендуем вам использовать более новую версию ключа с пометкой «Серверный ключ» в консоли Firebase .
Если вы хотите удалить существующий устаревший ключ сервера, вы можете сделать это в Google Cloud Console .
Авторизовать HTTP-запросы
Запрос сообщения состоит из двух частей: заголовка HTTP и тела HTTP. Заголовок HTTP должен содержать следующие заголовки:
-
Authorization
: key=YOUR_SERVER_KEY
Убедитесь, что это ключ сервера , значение которого доступно на вкладке Cloud Messaging панели настроек консоли 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\"]}"
Если вы получаете код состояния HTTP 401, ваш ключ сервера недействителен.
Авторизовать соединение XMPP
С помощью XMPP вы можете поддерживать постоянное асинхронное двунаправленное соединение с серверами FCM. Соединение можно использовать для отправки и получения сообщений между вашим сервером и устройствами ваших пользователей, подключенными к FCM.
Вы можете использовать большинство библиотек XMPP для управления долговременным подключением к FCM. Конечная точка XMPP работает по адресу fcm-xmpp.googleapis.com:5235
. При тестировании функциональности с нерабочими пользователями вместо этого следует подключиться к тестовому серверу по адресу fcm-xmpp.googleapis.com:5236
(обратите внимание на другой порт).
Регулярное тестирование в пре-продакшене (небольшая среда, в которой запускаются последние сборки FCM) полезно для изоляции реальных пользователей от тестового кода. Тестовые устройства и тестовый код, подключающиеся к fcm-xmpp.googleapis.com:5236
, должны использовать другой идентификатор отправителя FCM, чтобы избежать любых рисков отправки тестовых сообщений рабочим пользователям или отправки исходящих сообщений из рабочего трафика через тестовые соединения.
К соединению предъявляются два важных требования:
- Вы должны инициировать соединение Transport Layer Security (TLS). Обратите внимание, что в настоящее время FCM не поддерживает расширение STARTTLS .
- Для FCM требуется механизм аутентификации SASL PLAIN с использованием
<your_FCM_Sender_Id>@fcm.googleapis.com
( идентификатор отправителя FCM ) и ключа сервера в качестве пароля. Эти значения доступны на вкладке Cloud Messaging панели настроек консоли Firebase.
Если в какой-то момент соединение прервется, вы должны немедленно переподключиться. Нет необходимости отступать после отключения, которое происходит после аутентификации. Для каждого идентификатора отправителя FCM допускает 2500 параллельных подключений.
В следующих фрагментах показано, как выполнить аутентификацию и авторизацию для подключения 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 открывает соединение и запрашивает механизм аутентификации, включая метод 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 панели настроек консоли Firebase.
<auth mechanism="PLAIN" xmlns="urn:ietf:params:xml:ns:xmpp-sasl">MTI2MjAwMzQ3OTMzQHByb2plY3RzLmdjbS5hb mFTeUIzcmNaTmtmbnFLZEZiOW1oekNCaVlwT1JEQTJKV1d0dw==</auth>
ФКМ
<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">
ФКМ
<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>
ФКМ
<iq type="result"> <bind xmlns="urn:ietf:params:xml:ns:xmpp-bind"> <jid>SENDER_ID@fcm.googleapis.com/RESOURCE</jid> </bind> </iq>
Примечание. FCM не использует связанный ресурс при маршрутизации сообщений.
Подробную информацию о создании запросов на отправку см. в разделе Создание запросов на отправку. Справочник по устаревшему протоколу XMPP содержит список всех параметров, которые может содержать ваше сообщение.