Firebase дает вам полный контроль над аутентификацией, позволяя аутентифицировать пользователей или устройства с помощью безопасных веб-токенов JSON (JWT). Вы создаете эти токены на своем сервере, передаете их обратно на клиентское устройство, а затем используете их для аутентификации с помощью метода signInWithCustomToken()
.
Для этого необходимо создать конечную точку сервера, которая принимает учетные данные для входа, такие как имя пользователя и пароль, и, если учетные данные действительны, возвращает пользовательский JWT. Пользовательский JWT, возвращенный с вашего сервера, затем может использоваться клиентским устройством для аутентификации в Firebase ( iOS+ , Android , веб-сайт ). После аутентификации этот идентификатор будет использоваться при доступе к другим сервисам Firebase, таким как Firebase Realtime Database и Cloud Storage . Кроме того, содержимое JWT будет доступно в объекте auth
в ваших Realtime Database Security Rules и в объекте request.auth
в ваших Cloud Storage Security Rules .
Вы можете создать собственный токен с помощью Firebase Admin SDK или использовать стороннюю библиотеку JWT, если ваш сервер написан на языке, который Firebase изначально не поддерживает.
Прежде чем начать
Пользовательские токены представляют собой подписанные JWT, в которых закрытый ключ, используемый для подписи, принадлежит учетной записи службы Google. Существует несколько способов указать учетную запись службы Google, которая должна использоваться Firebase Admin SDK для подписи пользовательских токенов:
- Использование файла JSON учетной записи службы . Этот метод можно использовать в любой среде, но для этого необходимо упаковать файл JSON учетной записи службы вместе с кодом. Особое внимание необходимо уделить тому, чтобы JSON-файл служебной учетной записи не был доступен третьим лицам.
- Разрешение Admin SDK обнаружить учетную запись службы . Этот метод можно использовать в средах, управляемых Google, таких как Google Cloud Functions и App Engine . Возможно, вам придется настроить некоторые дополнительные разрешения через консоль Google Cloud .
- Использование идентификатора учетной записи службы . При использовании в среде, управляемой Google, этот метод будет подписывать токены с использованием ключа указанной учетной записи службы. Однако он использует удаленный веб-сервис, и вам, возможно, придется настроить дополнительные разрешения для этой учетной записи службы через консоль Google Cloud .
Использование файла JSON сервисного аккаунта
Файлы JSON учетных записей служб содержат всю информацию, соответствующую учетным записям служб (включая закрытый ключ RSA). Их можно загрузить из консоли Firebase . Следуйте инструкциям по настройке Admin SDK для получения дополнительной информации о том, как инициализировать Admin SDK с помощью файла JSON сервисного аккаунта.
Этот метод инициализации подходит для широкого спектра развертываний Admin SDK. Кроме того, он позволяет Admin SDK создавать и подписывать пользовательские токены локально, без каких-либо удаленных вызовов API. Основным недостатком этого подхода является то, что он требует, чтобы вы упаковали JSON-файл сервисной учетной записи вместе с вашим кодом. Также обратите внимание, что закрытый ключ в JSON-файле сервисного аккаунта является конфиденциальной информацией, и необходимо соблюдать особую осторожность, чтобы сохранить его конфиденциальность. В частности, воздержитесь от добавления файлов JSON сервисного аккаунта в общедоступный контроль версий.
Разрешение Admin SDK обнаружить сервисный аккаунт
Если ваш код развернут в среде, управляемой Google, Admin SDK может попытаться автоматически обнаружить способ подписи пользовательских токенов:
Если ваш код развернут в стандартной среде App Engine для Java, Python или Go, Admin SDK может использовать службу App Identity, присутствующую в этой среде, для подписи пользовательских токенов. Служба App Identity подписывает данные, используя учетную запись службы, предоставленную для вашего приложения Google App Engine.
Если ваш код развернут в какой-либо другой управляемой среде (например, Google Cloud Functions, Google Compute Engine), Firebase Admin SDK может автоматически обнаружить строку идентификатора учетной записи службы на локальном сервере метаданных . Обнаруженный идентификатор учетной записи службы затем используется вместе со службой IAM для удаленной подписи токенов.
Чтобы использовать эти методы подписи, инициализируйте SDK с учетными данными приложения Google по умолчанию и не указывайте строку идентификатора учетной записи службы:
initializeApp();
FirebaseApp.initializeApp();
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();
Чтобы протестировать тот же код локально, скачайте JSON-файл сервисного аккаунта и установите переменную среды GOOGLE_APPLICATION_CREDENTIALS
, чтобы она указывала на него.
Если Firebase Admin SDK должен обнаружить строку идентификатора учетной записи службы, он делает это, когда ваш код впервые создает пользовательский токен. Результат кэшируется и повторно используется для последующих операций подписи токена. Идентификатор автоматически обнаруженного сервисного аккаунта обычно является одним из сервисных аккаунтов по умолчанию, предоставляемых Google Cloud :
- Учетная запись службы Compute Engine по умолчанию
- Учетная запись службы облачных функций по умолчанию
Как и в случае с явно указанными идентификаторами учетных записей служб, автоматически обнаруживаемые идентификаторы учетных записей служб должны иметь разрешение iam.serviceAccounts.signBlob
, чтобы создание настраиваемых токенов работало. Возможно, вам придется использовать раздел IAM и администратора консоли Google Cloud , чтобы предоставить учетным записям служб по умолчанию необходимые разрешения. Дополнительные сведения см. в разделе «Устранение неполадок» ниже.
Использование идентификатора сервисной учетной записи
Чтобы обеспечить согласованность между различными частями вашего приложения, вы можете указать идентификатор учетной записи службы, ключи которой будут использоваться для подписи токенов при работе в среде, управляемой Google. Это может сделать политики IAM более простыми и безопасными, а также избежать необходимости включать JSON-файл учетной записи службы в ваш код.
Идентификатор сервисного аккаунта можно найти в консоли Google Cloud или в поле client_email
загруженного JSON-файла сервисного аккаунта. Идентификаторы учетных записей службы — это адреса электронной почты, имеющие следующий формат: <client-id>@<project-id>.iam.gserviceaccount.com
. Они однозначно идентифицируют учетные записи служб в проектах Firebase и Google Cloud .
Чтобы создать собственные токены с использованием отдельного идентификатора учетной записи службы, инициализируйте SDK, как показано ниже:
initializeApp({
serviceAccountId: 'my-client-id@my-project-id.iam.gserviceaccount.com',
});
FirebaseOptions options = FirebaseOptions.builder()
.setCredentials(GoogleCredentials.getApplicationDefault())
.setServiceAccountId("my-client-id@my-project-id.iam.gserviceaccount.com")
.build();
FirebaseApp.initializeApp(options);
options = {
'serviceAccountId': 'my-client-id@my-project-id.iam.gserviceaccount.com',
}
firebase_admin.initialize_app(options=options)
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)
}
FirebaseApp.Create(new AppOptions()
{
Credential = GoogleCredential.GetApplicationDefault(),
ServiceAccountId = "my-client-id@my-project-id.iam.gserviceaccount.com",
});
Идентификаторы учетных записей служб не являются конфиденциальной информацией, поэтому их раскрытие несущественно. Однако для подписи пользовательских токенов с помощью указанной учетной записи службы Firebase Admin SDK должен вызвать удаленную службу. Кроме того, вы также должны убедиться, что учетная запись службы, которую Admin SDK использует для выполнения этого вызова — обычно {project-name}@appspot.gserviceaccount.com
— имеет разрешение iam.serviceAccounts.signBlob
. Дополнительные сведения см. в разделе «Устранение неполадок» ниже.
Создавайте собственные токены с помощью Firebase Admin SDK.
В Firebase Admin SDK есть встроенный метод создания пользовательских токенов. Как минимум, вам необходимо предоставить uid
, который может быть любой строкой, но должен однозначно идентифицировать пользователя или устройство, аутентифицируемое вами. Срок действия этих токенов истекает через час.
const uid = 'some-uid';
getAuth()
.createCustomToken(uid)
.then((customToken) => {
// Send token back to client
})
.catch((error) => {
console.log('Error creating custom token:', error);
});
String uid = "some-uid";
String customToken = FirebaseAuth.getInstance().createCustomToken(uid);
// Send token back to client
uid = 'some-uid'
custom_token = auth.create_custom_token(uid)
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)
var uid = "some-uid";
string customToken = await FirebaseAuth.DefaultInstance.CreateCustomTokenAsync(uid);
// Send token back to client
Вы также можете при необходимости указать дополнительные утверждения, которые будут включены в пользовательский токен. Например, ниже в пользовательский токен добавлено поле premiumAccount
, которое будет доступно в объектах auth
/ request.auth
в ваших Правилах безопасности:
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);
});
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
uid = 'some-uid'
additional_claims = {
'premiumAccount': True
}
custom_token = auth.create_custom_token(uid, additional_claims)
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)
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
Зарезервированные пользовательские имена токенов
Войдите в систему, используя собственные токены на клиентах.
После создания пользовательского токена вам следует отправить его в клиентское приложение. Клиентское приложение выполняет аутентификацию с помощью специального токена, вызывая signInWithCustomToken()
:
Цель-C
[[FIRAuth auth] signInWithCustomToken:customToken
completion:^(FIRAuthDataResult * _Nullable authResult,
NSError * _Nullable error) {
// ...
}];
Быстрый
Auth.auth().signIn(withCustomToken: customToken ?? "") { user, error in
// ...
}
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);
}
}
});
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.AuthResult result = task.Result;
Debug.LogFormat("User signed in successfully: {0} ({1})",
result.User.DisplayName, result.User.UserId);
});
firebase::Future<firebase::auth::AuthResult> result =
auth->SignInWithCustomToken(custom_token);
firebase.auth().signInWithCustomToken(token)
.then((userCredential) => {
// Signed in
var user = userCredential.user;
// ...
})
.catch((error) => {
var errorCode = error.code;
var errorMessage = error.message;
// ...
});
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;
// ...
});
Если аутентификация прошла успешно, ваш пользователь теперь войдет в ваше клиентское приложение с учетной записью, указанной uid
, включенной в пользовательский токен. Если эта учетная запись ранее не существовала, для этого пользователя будет создана запись.
Точно так же, как и в случае с другими методами входа (такими как signInWithEmailAndPassword()
и signInWithCredential()
), объект auth
в ваших Realtime Database Security Rules и объект request.auth
в ваших Cloud Storage Security Rules будут заполнены идентификатором пользователя uid
. В этом случае uid
будет тот, который вы указали при создании пользовательского токена.
{
"rules": {
"adminContent": {
".read": "auth.uid === 'some-uid'"
}
}
}
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";
}
}
}
Если пользовательский токен содержит дополнительные утверждения, на них можно ссылаться из объекта auth.token
( Firebase Realtime Database ) или request.auth.token
( Cloud Storage ) в ваших правилах:
{
"rules": {
"premiumContent": {
".read": "auth.token.premiumAccount === true"
}
}
}
service firebase.storage {
match /b/<your-firebase-storage-bucket>/o {
match /premiumContent/{filename} {
allow read, write: if request.auth.token.premiumAccount == true;
}
}
}
Создавайте собственные токены с помощью сторонней библиотеки JWT.
Если ваша серверная часть написана на языке, для которого нет официального SDK администратора Firebase, вы все равно можете создавать собственные токены вручную. Сначала найдите стороннюю библиотеку JWT для вашего языка. Затем используйте эту библиотеку JWT для создания JWT, который включает следующие утверждения:
Пользовательские заявки на токены | ||
---|---|---|
alg | Алгоритм | "RS256" |
iss | Эмитент | Адрес электронной почты сервисного аккаунта вашего проекта |
sub | Предмет | Адрес электронной почты сервисного аккаунта вашего проекта |
aud | Аудитория | "https://identitytoolkit.googleapis.com/google.identity.identitytoolkit.v1.IdentityToolkit" |
iat | Выдано в срок | Текущее время в секундах с начала эпохи UNIX. |
exp | Срок годности | Время в секундах с начала эпохи UNIX, когда истекает срок действия токена. Это может быть максимум на 3600 секунд позже, чем iat .Примечание: это контролирует только время истечения срока действия самого пользовательского токена . Но как только вы войдете в систему с помощью signInWithCustomToken() , они останутся в системе до тех пор, пока их сеанс не будет признан недействительным или пользователь не выйдет из системы. |
uid | Уникальный идентификатор вошедшего пользователя должен представлять собой строку длиной от 1 до 128 символов включительно. Более короткие uid обеспечивают лучшую производительность. | |
claims (необязательно) | Необязательные пользовательские утверждения для включения в переменные auth / request.auth правил безопасности. |
Вот несколько примеров реализации создания пользовательских токенов на различных языках, которые Firebase Admin SDK не поддерживает:
Использование 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");
}
Использование 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
После создания пользовательского токена отправьте его в свое клиентское приложение, чтобы использовать его для аутентификации в Firebase. См. примеры кода выше, чтобы узнать, как это сделать.
Поиск неисправностей
В этом разделе описаны некоторые распространенные проблемы, с которыми могут столкнуться разработчики при создании пользовательских токенов, а также способы их решения.
IAM API не включен
Если вы указываете идентификатор учетной записи службы для подписи токенов, вы можете получить ошибку, подобную следующей:
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.
Firebase Admin SDK использует IAM API для подписи токенов. Эта ошибка указывает на то, что API IAM в настоящее время не включен для вашего проекта Firebase. Откройте ссылку в сообщении об ошибке в веб-браузере и нажмите кнопку «Включить API», чтобы включить его для своего проекта.
У учетной записи службы нет необходимых разрешений
Если учетная запись службы, под которой работает Firebase Admin SDK, не имеет разрешения iam.serviceAccounts.signBlob
, вы можете получить сообщение об ошибке, подобное следующему:
Permission iam.serviceAccounts.signBlob is required to perform this operation on service account projects/-/serviceAccounts/{your-service-account-id}.
Самый простой способ решить эту проблему — предоставить роль IAM «Создатель токена сервисной учетной записи» соответствующей сервисной учетной записи, обычно {project-name}@appspot.gserviceaccount.com
:
- Откройте IAM и страницу администрирования в консоли Google Cloud .
- Выберите свой проект и нажмите «Продолжить».
- Нажмите значок редактирования, соответствующий учетной записи службы, которую вы хотите обновить.
- Нажмите «Добавить еще одну роль».
- Введите «Создатель токена учетной записи службы» в фильтр поиска и выберите его из результатов.
- Нажмите «Сохранить», чтобы подтвердить предоставление роли.
Обратитесь к документации IAM для получения более подробной информации об этом процессе или узнайте, как выполнять обновление ролей с помощью инструментов командной строки gcloud.
Не удалось определить учетную запись службы
Если вы получаете сообщение об ошибке, подобное следующему, значит, Firebase Admin SDK не был правильно инициализирован.
Failed to determine service account ID. Initialize the SDK with service account credentials or specify a service account ID with iam.serviceAccounts.signBlob permission.
Если вы полагаетесь на SDK для автоматического обнаружения идентификатора сервисного аккаунта, убедитесь, что код развернут в управляемой среде Google с сервером метаданных. В противном случае обязательно укажите файл JSON учетной записи службы или идентификатор учетной записи службы при инициализации SDK.
, Firebase дает вам полный контроль над аутентификацией, позволяя аутентифицировать пользователей или устройства с помощью безопасных веб-токенов JSON (JWT). Вы создаете эти токены на своем сервере, передаете их обратно на клиентское устройство, а затем используете их для аутентификации с помощью метода signInWithCustomToken()
.
Для этого необходимо создать конечную точку сервера, которая принимает учетные данные для входа, такие как имя пользователя и пароль, и, если учетные данные действительны, возвращает пользовательский JWT. Пользовательский JWT, возвращенный с вашего сервера, затем может использоваться клиентским устройством для аутентификации в Firebase ( iOS+ , Android , веб-сайт ). После аутентификации этот идентификатор будет использоваться при доступе к другим сервисам Firebase, таким как Firebase Realtime Database и Cloud Storage . Кроме того, содержимое JWT будет доступно в объекте auth
в ваших Realtime Database Security Rules и в объекте request.auth
в ваших Cloud Storage Security Rules .
Вы можете создать собственный токен с помощью Firebase Admin SDK или использовать стороннюю библиотеку JWT, если ваш сервер написан на языке, который Firebase изначально не поддерживает.
Прежде чем начать
Пользовательские токены представляют собой подписанные JWT, в которых закрытый ключ, используемый для подписи, принадлежит учетной записи службы Google. Существует несколько способов указать учетную запись службы Google, которая должна использоваться Firebase Admin SDK для подписи пользовательских токенов:
- Использование файла JSON учетной записи службы . Этот метод можно использовать в любой среде, но для этого необходимо упаковать файл JSON учетной записи службы вместе с кодом. Особое внимание необходимо уделить тому, чтобы JSON-файл служебной учетной записи не был доступен третьим лицам.
- Разрешение Admin SDK обнаружить учетную запись службы . Этот метод можно использовать в средах, управляемых Google, таких как Google Cloud Functions и App Engine . Возможно, вам придется настроить некоторые дополнительные разрешения через консоль Google Cloud .
- Использование идентификатора учетной записи службы . При использовании в среде, управляемой Google, этот метод будет подписывать токены с использованием ключа указанной учетной записи службы. Однако он использует удаленный веб-сервис, и вам, возможно, придется настроить дополнительные разрешения для этой учетной записи службы через консоль Google Cloud .
Использование файла JSON сервисного аккаунта
Файлы JSON учетных записей служб содержат всю информацию, соответствующую учетным записям служб (включая закрытый ключ RSA). Их можно загрузить из консоли Firebase . Следуйте инструкциям по настройке Admin SDK для получения дополнительной информации о том, как инициализировать Admin SDK с помощью файла JSON сервисного аккаунта.
Этот метод инициализации подходит для широкого спектра развертываний Admin SDK. Кроме того, он позволяет Admin SDK создавать и подписывать пользовательские токены локально, без каких-либо удаленных вызовов API. Основным недостатком этого подхода является то, что он требует, чтобы вы упаковали JSON-файл сервисной учетной записи вместе с вашим кодом. Также обратите внимание, что закрытый ключ в JSON-файле сервисного аккаунта является конфиденциальной информацией, и необходимо соблюдать особую осторожность, чтобы сохранить его конфиденциальность. В частности, воздержитесь от добавления файлов JSON сервисного аккаунта в общедоступный контроль версий.
Разрешение Admin SDK обнаружить сервисный аккаунт
Если ваш код развернут в среде, управляемой Google, Admin SDK может попытаться автоматически обнаружить способ подписи пользовательских токенов:
Если ваш код развернут в стандартной среде App Engine для Java, Python или Go, Admin SDK может использовать службу App Identity, присутствующую в этой среде, для подписи пользовательских токенов. Служба App Identity подписывает данные, используя учетную запись службы, предоставленную для вашего приложения Google App Engine.
Если ваш код развернут в какой-либо другой управляемой среде (например, Google Cloud Functions, Google Compute Engine), Firebase Admin SDK может автоматически обнаружить строку идентификатора сервисной учетной записи на локальном сервере метаданных . Обнаруженный идентификатор учетной записи службы затем используется вместе со службой IAM для удаленной подписи токенов.
Чтобы использовать эти методы подписи, инициализируйте SDK с учетными данными приложения Google по умолчанию и не указывайте строку идентификатора учетной записи службы:
initializeApp();
FirebaseApp.initializeApp();
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();
Чтобы протестировать тот же код локально, скачайте JSON-файл сервисного аккаунта и установите переменную среды GOOGLE_APPLICATION_CREDENTIALS
, чтобы она указывала на него.
Если Firebase Admin SDK должен обнаружить строку идентификатора учетной записи службы, он делает это, когда ваш код впервые создает пользовательский токен. Результат кэшируется и повторно используется для последующих операций подписи токена. Идентификатор автоматически обнаруженного сервисного аккаунта обычно является одним из сервисных аккаунтов по умолчанию, предоставляемых Google Cloud :
- Учетная запись службы Compute Engine по умолчанию
- Учетная запись службы облачных функций по умолчанию
Как и в случае с явно заданными идентификаторами учетных записей служб, автоматически обнаруживаемые идентификаторы учетных записей служб должны иметь разрешение iam.serviceAccounts.signBlob
, чтобы создание настраиваемых токенов работало. Возможно, вам придется использовать раздел IAM и администратора консоли Google Cloud , чтобы предоставить учетным записям служб по умолчанию необходимые разрешения. Дополнительные сведения см. в разделе «Устранение неполадок» ниже.
Использование идентификатора сервисной учетной записи
Чтобы обеспечить согласованность между различными частями вашего приложения, вы можете указать идентификатор учетной записи службы, ключи которой будут использоваться для подписи токенов при работе в среде, управляемой Google. Это может сделать политики IAM более простыми и безопасными, а также избежать необходимости включать JSON-файл учетной записи службы в ваш код.
Идентификатор сервисного аккаунта можно найти в консоли Google Cloud или в поле client_email
загруженного JSON-файла сервисного аккаунта. Идентификаторы учетных записей службы — это адреса электронной почты, имеющие следующий формат: <client-id>@<project-id>.iam.gserviceaccount.com
. Они однозначно идентифицируют учетные записи служб в проектах Firebase и Google Cloud .
Чтобы создать собственные токены с использованием отдельного идентификатора учетной записи службы, инициализируйте SDK, как показано ниже:
initializeApp({
serviceAccountId: 'my-client-id@my-project-id.iam.gserviceaccount.com',
});
FirebaseOptions options = FirebaseOptions.builder()
.setCredentials(GoogleCredentials.getApplicationDefault())
.setServiceAccountId("my-client-id@my-project-id.iam.gserviceaccount.com")
.build();
FirebaseApp.initializeApp(options);
options = {
'serviceAccountId': 'my-client-id@my-project-id.iam.gserviceaccount.com',
}
firebase_admin.initialize_app(options=options)
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)
}
FirebaseApp.Create(new AppOptions()
{
Credential = GoogleCredential.GetApplicationDefault(),
ServiceAccountId = "my-client-id@my-project-id.iam.gserviceaccount.com",
});
Идентификаторы учетных записей служб не являются конфиденциальной информацией, поэтому их раскрытие несущественно. Однако для подписи пользовательских токенов с помощью указанной учетной записи службы Firebase Admin SDK должен вызвать удаленную службу. Кроме того, вы также должны убедиться, что учетная запись службы, которую Admin SDK использует для выполнения этого вызова — обычно {project-name}@appspot.gserviceaccount.com
— имеет разрешение iam.serviceAccounts.signBlob
. Дополнительные сведения см. в разделе «Устранение неполадок» ниже.
Создавайте собственные токены с помощью Firebase Admin SDK.
В Firebase Admin SDK есть встроенный метод создания пользовательских токенов. Как минимум, вам необходимо предоставить uid
, который может быть любой строкой, но должен однозначно идентифицировать пользователя или устройство, аутентифицируемое вами. Срок действия этих токенов истекает через час.
const uid = 'some-uid';
getAuth()
.createCustomToken(uid)
.then((customToken) => {
// Send token back to client
})
.catch((error) => {
console.log('Error creating custom token:', error);
});
String uid = "some-uid";
String customToken = FirebaseAuth.getInstance().createCustomToken(uid);
// Send token back to client
uid = 'some-uid'
custom_token = auth.create_custom_token(uid)
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)
var uid = "some-uid";
string customToken = await FirebaseAuth.DefaultInstance.CreateCustomTokenAsync(uid);
// Send token back to client
Вы также можете при необходимости указать дополнительные утверждения, которые будут включены в пользовательский токен. Например, ниже в пользовательский токен добавлено поле premiumAccount
, которое будет доступно в объектах auth
/ request.auth
в ваших Правилах безопасности:
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);
});
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
uid = 'some-uid'
additional_claims = {
'premiumAccount': True
}
custom_token = auth.create_custom_token(uid, additional_claims)
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)
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
Зарезервированные пользовательские имена токенов
Войдите в систему, используя собственные токены на клиентах.
После создания пользовательского токена вам следует отправить его в клиентское приложение. Клиентское приложение выполняет аутентификацию с помощью специального токена, вызывая signInWithCustomToken()
:
Цель-C
[[FIRAuth auth] signInWithCustomToken:customToken
completion:^(FIRAuthDataResult * _Nullable authResult,
NSError * _Nullable error) {
// ...
}];
Быстрый
Auth.auth().signIn(withCustomToken: customToken ?? "") { user, error in
// ...
}
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);
}
}
});
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.AuthResult result = task.Result;
Debug.LogFormat("User signed in successfully: {0} ({1})",
result.User.DisplayName, result.User.UserId);
});
firebase::Future<firebase::auth::AuthResult> result =
auth->SignInWithCustomToken(custom_token);
firebase.auth().signInWithCustomToken(token)
.then((userCredential) => {
// Signed in
var user = userCredential.user;
// ...
})
.catch((error) => {
var errorCode = error.code;
var errorMessage = error.message;
// ...
});
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;
// ...
});
Если аутентификация прошла успешно, ваш пользователь теперь войдет в ваше клиентское приложение с учетной записью, указанной uid
, включенной в пользовательский токен. Если эта учетная запись ранее не существовала, для этого пользователя будет создана запись.
Как и в случае с другими методами входа (такими как signInWithEmailAndPassword()
и signInWithCredential()
), объект auth
в ваших Realtime Database Security Rules и объект request.auth
в ваших Cloud Storage Security Rules будут заполнены идентификатором пользователя uid
. В этом случае uid
будет тот, который вы указали при создании пользовательского токена.
{
"rules": {
"adminContent": {
".read": "auth.uid === 'some-uid'"
}
}
}
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";
}
}
}
Если пользовательский токен содержит дополнительные утверждения, на них можно ссылаться из объекта auth.token
( Firebase Realtime Database ) или request.auth.token
( Cloud Storage ) в ваших правилах:
{
"rules": {
"premiumContent": {
".read": "auth.token.premiumAccount === true"
}
}
}
service firebase.storage {
match /b/<your-firebase-storage-bucket>/o {
match /premiumContent/{filename} {
allow read, write: if request.auth.token.premiumAccount == true;
}
}
}
Создавайте собственные токены с помощью сторонней библиотеки JWT.
Если ваша серверная часть написана на языке, для которого нет официального SDK администратора Firebase, вы все равно можете создавать собственные токены вручную. Сначала найдите стороннюю библиотеку JWT для вашего языка. Затем используйте эту библиотеку JWT для создания JWT, который включает следующие утверждения:
Пользовательские заявки на токены | ||
---|---|---|
alg | Алгоритм | "RS256" |
iss | Эмитент | Адрес электронной почты сервисного аккаунта вашего проекта |
sub | Предмет | Адрес электронной почты сервисного аккаунта вашего проекта |
aud | Аудитория | "https://identitytoolkit.googleapis.com/google.identity.identitytoolkit.v1.IdentityToolkit" |
iat | Выдано в срок | Текущее время в секундах с начала эпохи UNIX. |
exp | Срок годности | Время в секундах с начала эпохи UNIX, когда истекает срок действия токена. Это может быть максимум на 3600 секунд позже, чем iat .Примечание: это контролирует только время истечения срока действия самого пользовательского токена . Но как только вы войдете в систему с помощью signInWithCustomToken() , они останутся в системе до тех пор, пока их сеанс не станет недействительным или пока пользователь не выйдет из системы. |
uid | Уникальный идентификатор вошедшего пользователя должен представлять собой строку длиной от 1 до 128 символов включительно. Более короткие uid обеспечивают лучшую производительность. | |
claims (необязательно) | Необязательные пользовательские утверждения для включения в переменные auth / request.auth правил безопасности. |
Вот несколько примеров реализации создания пользовательских токенов на различных языках, которые Firebase Admin SDK не поддерживает:
Использование 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");
}
Использование 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
После создания пользовательского токена отправьте его в свое клиентское приложение, чтобы использовать его для аутентификации в Firebase. См. примеры кода выше, чтобы узнать, как это сделать.
Поиск неисправностей
В этом разделе описаны некоторые распространенные проблемы, с которыми могут столкнуться разработчики при создании пользовательских токенов, а также способы их решения.
IAM API не включен
Если вы указываете идентификатор учетной записи службы для подписи токенов, вы можете получить ошибку, подобную следующей:
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.
Firebase Admin SDK использует IAM API для подписи токенов. Эта ошибка указывает на то, что API IAM в настоящее время не включен для вашего проекта Firebase. Откройте ссылку в сообщении об ошибке в веб-браузере и нажмите кнопку «Включить API», чтобы включить его для своего проекта.
У учетной записи службы нет необходимых разрешений
Если учетная запись службы, под которой работает Firebase Admin SDK, не имеет разрешения iam.serviceAccounts.signBlob
, вы можете получить сообщение об ошибке, подобное следующему:
Permission iam.serviceAccounts.signBlob is required to perform this operation on service account projects/-/serviceAccounts/{your-service-account-id}.
Самый простой способ решить эту проблему — предоставить роль IAM «Создатель токена сервисной учетной записи» соответствующей сервисной учетной записи, обычно {project-name}@appspot.gserviceaccount.com
:
- Откройте IAM и страницу администрирования в консоли Google Cloud .
- Выберите свой проект и нажмите «Продолжить».
- Нажмите значок редактирования, соответствующий учетной записи службы, которую вы хотите обновить.
- Нажмите «Добавить еще одну роль».
- Введите «Создатель токена учетной записи службы» в фильтр поиска и выберите его из результатов.
- Нажмите «Сохранить», чтобы подтвердить предоставление роли.
Обратитесь к документации IAM для получения более подробной информации об этом процессе или узнайте, как выполнять обновление ролей с помощью инструментов командной строки gcloud.
Не удалось определить учетную запись службы
Если вы получаете сообщение об ошибке, подобное следующему, значит, Firebase Admin SDK не был правильно инициализирован.
Failed to determine service account ID. Initialize the SDK with service account credentials or specify a service account ID with iam.serviceAccounts.signBlob permission.
Если вы полагаетесь на SDK для автоматического обнаружения идентификатора сервисного аккаунта, убедитесь, что код развернут в управляемой среде Google с сервером метаданных. В противном случае обязательно укажите файл JSON учетной записи службы или идентификатор учетной записи службы при инициализации SDK.
, Firebase дает вам полный контроль над аутентификацией, позволяя аутентифицировать пользователей или устройства с помощью безопасных веб-токенов JSON (JWT). Вы создаете эти токены на своем сервере, передаете их обратно на клиентское устройство, а затем используете их для аутентификации с помощью метода signInWithCustomToken()
.
Для этого необходимо создать конечную точку сервера, которая принимает учетные данные для входа, такие как имя пользователя и пароль, и, если учетные данные действительны, возвращает пользовательский JWT. Пользовательский JWT, возвращенный с вашего сервера, затем может использоваться клиентским устройством для аутентификации в Firebase ( iOS+ , Android , веб-сайт ). После аутентификации этот идентификатор будет использоваться при доступе к другим сервисам Firebase, таким как Firebase Realtime Database и Cloud Storage . Кроме того, содержимое JWT будет доступно в объекте auth
в ваших Realtime Database Security Rules и в объекте request.auth
в ваших Cloud Storage Security Rules .
Вы можете создать собственный токен с помощью Firebase Admin SDK или использовать стороннюю библиотеку JWT, если ваш сервер написан на языке, который Firebase изначально не поддерживает.
Прежде чем начать
Пользовательские токены представляют собой подписанные JWT, в которых закрытый ключ, используемый для подписи, принадлежит учетной записи службы Google. Существует несколько способов указать учетную запись службы Google, которая должна использоваться Firebase Admin SDK для подписи пользовательских токенов:
- Использование файла JSON учетной записи службы . Этот метод можно использовать в любой среде, но для этого необходимо упаковать файл JSON учетной записи службы вместе с кодом. Особое внимание необходимо уделить тому, чтобы JSON-файл служебной учетной записи не был доступен третьим лицам.
- Разрешение Admin SDK обнаружить учетную запись службы . Этот метод можно использовать в средах, управляемых Google, таких как Google Cloud Functions и App Engine . Возможно, вам придется настроить некоторые дополнительные разрешения через консоль Google Cloud .
- Использование идентификатора учетной записи службы . При использовании в среде, управляемой Google, этот метод будет подписывать токены с использованием ключа указанной учетной записи службы. Однако он использует удаленный веб-сервис, и вам, возможно, придется настроить дополнительные разрешения для этой учетной записи службы через консоль Google Cloud .
Использование файла JSON сервисного аккаунта
Файлы JSON учетных записей служб содержат всю информацию, соответствующую учетным записям служб (включая закрытый ключ RSA). Их можно загрузить из консоли Firebase . Следуйте инструкциям по настройке Admin SDK для получения дополнительной информации о том, как инициализировать Admin SDK с помощью файла JSON сервисного аккаунта.
Этот метод инициализации подходит для широкого спектра развертываний Admin SDK. Кроме того, он позволяет Admin SDK создавать и подписывать пользовательские токены локально, без каких-либо удаленных вызовов API. Основным недостатком этого подхода является то, что он требует, чтобы вы упаковали JSON-файл сервисной учетной записи вместе с вашим кодом. Также обратите внимание, что закрытый ключ в JSON-файле сервисного аккаунта является конфиденциальной информацией, и необходимо соблюдать особую осторожность, чтобы сохранить его конфиденциальность. В частности, воздержитесь от добавления файлов JSON сервисного аккаунта в общедоступный контроль версий.
Разрешение Admin SDK обнаружить сервисный аккаунт
Если ваш код развернут в среде, управляемой Google, Admin SDK может попытаться автоматически обнаружить способ подписи пользовательских токенов:
Если ваш код развернут в стандартной среде App Engine для Java, Python или Go, Admin SDK может использовать службу App Identity, присутствующую в этой среде, для подписи пользовательских токенов. Служба App Identity подписывает данные, используя учетную запись службы, предоставленную для вашего приложения Google App Engine.
Если ваш код развернут в какой-либо другой управляемой среде (например, Google Cloud Functions, Google Compute Engine), Firebase Admin SDK может автоматически обнаружить строку идентификатора сервисной учетной записи на локальном сервере метаданных . Обнаруженный идентификатор учетной записи службы затем используется вместе со службой IAM для удаленной подписи токенов.
Чтобы использовать эти методы подписи, инициализируйте SDK с учетными данными приложения Google по умолчанию и не указывайте строку идентификатора учетной записи службы:
initializeApp();
FirebaseApp.initializeApp();
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();
Чтобы протестировать тот же код локально, скачайте JSON-файл сервисного аккаунта и установите переменную среды GOOGLE_APPLICATION_CREDENTIALS
, чтобы она указывала на него.
Если Firebase Admin SDK должен обнаружить строку идентификатора учетной записи службы, он делает это, когда ваш код впервые создает пользовательский токен. Результат кэшируется и повторно используется для последующих операций подписи токена. Идентификатор автоматически обнаруженного сервисного аккаунта обычно является одним из сервисных аккаунтов по умолчанию, предоставляемых Google Cloud :
- Учетная запись службы Compute Engine по умолчанию
- Учетная запись службы облачных функций по умолчанию
Как и в случае с явно заданными идентификаторами учетных записей служб, автоматически обнаруживаемые идентификаторы учетных записей служб должны иметь разрешение iam.serviceAccounts.signBlob
, чтобы создание настраиваемых токенов работало. Возможно, вам придется использовать раздел IAM и администратора консоли Google Cloud , чтобы предоставить учетным записям служб по умолчанию необходимые разрешения. Дополнительные сведения см. в разделе «Устранение неполадок» ниже.
Использование идентификатора сервисной учетной записи
Чтобы обеспечить согласованность между различными частями вашего приложения, вы можете указать идентификатор учетной записи службы, ключи которой будут использоваться для подписи токенов при работе в среде, управляемой Google. Это может сделать политики IAM более простыми и безопасными, а также избежать необходимости включать JSON-файл учетной записи службы в ваш код.
Идентификатор сервисного аккаунта можно найти в консоли Google Cloud или в поле client_email
загруженного JSON-файла сервисного аккаунта. Идентификаторы учетных записей службы — это адреса электронной почты, имеющие следующий формат: <client-id>@<project-id>.iam.gserviceaccount.com
. Они однозначно идентифицируют учетные записи служб в проектах Firebase и Google Cloud .
Чтобы создать собственные токены с использованием отдельного идентификатора учетной записи службы, инициализируйте SDK, как показано ниже:
initializeApp({
serviceAccountId: 'my-client-id@my-project-id.iam.gserviceaccount.com',
});
FirebaseOptions options = FirebaseOptions.builder()
.setCredentials(GoogleCredentials.getApplicationDefault())
.setServiceAccountId("my-client-id@my-project-id.iam.gserviceaccount.com")
.build();
FirebaseApp.initializeApp(options);
options = {
'serviceAccountId': 'my-client-id@my-project-id.iam.gserviceaccount.com',
}
firebase_admin.initialize_app(options=options)
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)
}
FirebaseApp.Create(new AppOptions()
{
Credential = GoogleCredential.GetApplicationDefault(),
ServiceAccountId = "my-client-id@my-project-id.iam.gserviceaccount.com",
});
Идентификаторы учетных записей служб не являются конфиденциальной информацией, поэтому их раскрытие несущественно. Однако для подписи пользовательских токенов с помощью указанной учетной записи службы Firebase Admin SDK должен вызвать удаленную службу. Кроме того, вы также должны убедиться, что учетная запись службы, которую Admin SDK использует для выполнения этого вызова — обычно {project-name}@appspot.gserviceaccount.com
— имеет разрешение iam.serviceAccounts.signBlob
. Дополнительные сведения см. в разделе «Устранение неполадок» ниже.
Создавайте собственные токены с помощью Firebase Admin SDK.
В Firebase Admin SDK есть встроенный метод создания пользовательских токенов. Как минимум, вам необходимо предоставить uid
, который может быть любой строкой, но должен однозначно идентифицировать пользователя или устройство, аутентифицируемое вами. Срок действия этих токенов истекает через один час.
const uid = 'some-uid';
getAuth()
.createCustomToken(uid)
.then((customToken) => {
// Send token back to client
})
.catch((error) => {
console.log('Error creating custom token:', error);
});
String uid = "some-uid";
String customToken = FirebaseAuth.getInstance().createCustomToken(uid);
// Send token back to client
uid = 'some-uid'
custom_token = auth.create_custom_token(uid)
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)
var uid = "some-uid";
string customToken = await FirebaseAuth.DefaultInstance.CreateCustomTokenAsync(uid);
// Send token back to client
Вы также можете при необходимости указать дополнительные утверждения, которые будут включены в пользовательский токен. Например, ниже в пользовательский токен добавлено поле premiumAccount
, которое будет доступно в объектах auth
/ request.auth
в ваших Правилах безопасности:
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);
});
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
uid = 'some-uid'
additional_claims = {
'premiumAccount': True
}
custom_token = auth.create_custom_token(uid, additional_claims)
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)
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
Зарезервированные пользовательские имена токенов
Войдите в систему, используя собственные токены на клиентах.
После создания пользовательского токена вам следует отправить его в клиентское приложение. Клиентское приложение аутентифицируется с помощью специального токена, вызывая signInWithCustomToken()
:
Цель-C
[[FIRAuth auth] signInWithCustomToken:customToken
completion:^(FIRAuthDataResult * _Nullable authResult,
NSError * _Nullable error) {
// ...
}];
Быстрый
Auth.auth().signIn(withCustomToken: customToken ?? "") { user, error in
// ...
}
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);
}
}
});
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.AuthResult result = task.Result;
Debug.LogFormat("User signed in successfully: {0} ({1})",
result.User.DisplayName, result.User.UserId);
});
firebase::Future<firebase::auth::AuthResult> result =
auth->SignInWithCustomToken(custom_token);
firebase.auth().signInWithCustomToken(token)
.then((userCredential) => {
// Signed in
var user = userCredential.user;
// ...
})
.catch((error) => {
var errorCode = error.code;
var errorMessage = error.message;
// ...
});
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;
// ...
});
Если аутентификация прошла успешно, ваш пользователь теперь войдет в ваше клиентское приложение с учетной записью, указанной uid
, включенной в пользовательский токен. Если эта учетная запись ранее не существовала, для этого пользователя будет создана запись.
Точно так же, как и в случае с другими методами входа (такими как signInWithEmailAndPassword()
и signInWithCredential()
), объект auth
в ваших Realtime Database Security Rules и объект request.auth
в ваших Cloud Storage Security Rules будут заполнены идентификатором пользователя uid
. В этом случае uid
будет тот, который вы указали при создании пользовательского токена.
{
"rules": {
"adminContent": {
".read": "auth.uid === 'some-uid'"
}
}
}
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";
}
}
}
Если пользовательский токен Cloud Storage дополнительные претензии, их можно ссылаться на объект auth.token
( Firebase Realtime Database ) или request.auth.token
.
{
"rules": {
"premiumContent": {
".read": "auth.token.premiumAccount === true"
}
}
}
service firebase.storage {
match /b/<your-firebase-storage-bucket>/o {
match /premiumContent/{filename} {
allow read, write: if request.auth.token.premiumAccount == true;
}
}
}
Создать пользовательские токены с использованием сторонней библиотеки JWT
Если ваш бэкэнд находится на языке, у которого нет официального SDK Firebase Admin SDK, вы все равно можете вручную создавать пользовательские токены. Во-первых, найдите стороннюю библиотеку JWT для вашего языка. Затем используйте эту библиотеку JWT для Mint A JWT, который включает в себя следующие претензии:
Пользовательские претензии | ||
---|---|---|
alg | Алгоритм | "RS256" |
iss | Эмитент | Адрес электронной почты вашего проекта в сфере услуг |
sub | Предмет | Адрес электронной почты вашего проекта в сфере услуг |
aud | Аудитория | "https://identitytoolkit.googleapis.com/google.identity.identitytoolkit.v1.IdentityToolkit" |
iat | Выпущено в время | Текущее время, за несколько секунд с момента эпохи UNIX |
exp | Срок годности | Время, за несколько секунд после эпохи UNIX, в которой срок действия токена истекает. Это может быть максимум на 3600 секунд позже iat .Примечание. Это контролирует только время, когда истекает сам таковой токен . Но как только вы подписываете пользователя в использовании signInWithCustomToken() , он останется подписанными в устройство до тех пор, пока их сеанс не будет признан недействительным или пользовательским выведением. |
uid | Уникальный идентификатор подписанного пользователя должен быть строкой, от 1 до 128 символов, включительно. Более короткий uid S предлагает лучшую производительность. | |
claims (необязательно) | Необязательные пользовательские претензии на включение в правила безопасности auth / request.auth переменные |
Вот несколько примеров реализаций того, как создавать пользовательские токены на различных языках, которые не поддерживает Admin SDK Firebase Admin SDK:
Использование 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");
}
Использование 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
После создания пользовательского токена отправьте его в свое клиентское приложение для аутентификации с Firebase. Смотрите приведенные выше образцы кода для того, как это сделать.
Поиск неисправностей
В этом разделе изложены некоторые общие проблемы, которые разработчики могут столкнуться при создании пользовательских токенов и как их решить.
IAM API не включен
Если вы указываете идентификатор учетной записи службы для подписи токенов, вы можете получить ошибку, аналогичную следующему:
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.
Admin SDK Firebase использует API IAM для подписи токенов. Эта ошибка указывает на то, что IAM API в настоящее время не включен для вашего проекта Firebase. Откройте ссылку в сообщении об ошибке в веб -браузере и нажмите кнопку «Включить API», чтобы включить ее для вашего проекта.
Сервисная учетная запись не требует разрешений
Если с учетом обслуживания работает Admin SDK Firebase Admin, а также нет разрешения iam.serviceAccounts.signBlob
, вы можете получить сообщение об ошибке, как следующее:
Permission iam.serviceAccounts.signBlob is required to perform this operation on service account projects/-/serviceAccounts/{your-service-account-id}.
Самый простой способ разрешить это-предоставить роль «создателя токена услуг» в рассматриваемой учетной записи, обычно {project-name}@appspot.gserviceaccount.com
- Откройте страницу IAM и Admin в консоли Google Cloud .
- Выберите свой проект и нажмите «Продолжить».
- Нажмите на значок «Редактировать», соответствующий учетной записи службы, которую вы хотите обновить.
- Нажмите «Добавить другую роль».
- Введите «Создатель токена учетной записи службы» в поисковый фильтр и выберите его из результатов.
- Нажмите «Сохранить», чтобы подтвердить грант роли.
Обратитесь к документации IAM для получения более подробной информации об этом процессе или узнайте, как выполнять роли обновления, используя инструменты командной строки GCLOUD.
Не удалось определить учетную запись службы
Если вы получите сообщение об ошибке, аналогичное следующему, Admin SDK Firebase не был должным образом инициализирован.
Failed to determine service account ID. Initialize the SDK with service account credentials or specify a service account ID with iam.serviceAccounts.signBlob permission.
Если вы полагаетесь на SDK для автоматического раскрытия идентификатора учетной записи службы, убедитесь, что код развернут в управляемой среде Google с сервером метаданных. В противном случае, обязательно укажите файл файла JSON или идентификатор службы с учетной записью службы на идентификации SDK инициализации.
, Firebase дает вам полный контроль над аутентификацией, позволяя вам аутентифицировать пользователей или устройства, используя Secure JSON Web Tokens (JWTS). Вы генерируете эти токены на своем сервере, передаете их обратно к клиентскому устройству, а затем используете их для аутентификации с помощью метода signInWithCustomToken()
.
Чтобы достичь этого, вы должны создать конечную точку сервера, которая принимает учетные данные входа, например, как имя пользователя и пароль-и, если учетные данные действительны, возвращает пользовательский JWT. Пользовательский JWT, возвращаемый с вашего сервера, может затем использоваться клиентским устройством для аутентификации Firebase ( iOS+ , Android , Web ). После аутентификации эта личность будет использоваться при доступе к другим службам Firebase, таким как Firebase Realtime Database и Cloud Storage . Кроме того, содержимое JWT будет доступно в объекте auth
в ваших Realtime Database Security Rules и объекте request.auth
в ваших Cloud Storage Security Rules .
Вы можете создать пользовательский токен с Admin SDK Firebase, или вы можете использовать стороннюю библиотеку JWT, если ваш сервер написан на языке, который Firebase не поддерживает.
Прежде чем начать
Пользовательские токены подписаны JWT, где закрытый ключ, используемый для подписания, принадлежит учетной записи службы Google. Есть несколько способов указать учетную запись службы Google, которая должна использоваться Admin SDK Firebase для подписания пользовательских токенов:
- Использование файла JSON Service Account - этот метод можно использовать в любой среде, но требует, чтобы вы упаковали файл JSON Service Account вместе с вашим кодом. Следует принять особое осторожность, чтобы гарантировать, что файл JSON Service не подвергался внешним сторонам.
- Позвольте администратору SDK обнаружить учетную запись службы - этот метод может использоваться в средах, управляемых Google, такими как Google Cloud Functions и App Engine . Возможно, вам придется настроить некоторые дополнительные разрешения через Google Cloud .
- Используя идентификатор учетной записи службы -при использовании в среде, управляемой Google, этот метод будет подписывать токены, используя указанную учетную запись службы. Тем не менее, он использует удаленную веб -службу, и вам, возможно, придется настроить дополнительные разрешения для этой учетной записи службы через Google Cloud .
Использование файла JSON Service Account
Служба учетная запись JSON Files содержат всю информацию, соответствующую учетным записям услуг (включая частный ключ RSA). Их можно скачать с консоли Firebase . Следите за инструкциями Admin SDK для получения дополнительной информации о том, как инициализировать Admin SDK с помощью файла JSON Service Account.
Этот метод инициализации подходит для широкого диапазона развертываний администратора SDK. Также это позволяет администратору SDK создавать и подписывать пользовательские токены локально, не делая удаленных вызовов API. Основным недостатком этого подхода является то, что он требует, чтобы вы упаковали файл JSON Service Account вместе с вашим кодом. Также обратите внимание, что закрытый ключ в файле JSON Service Account Accounte является конфиденциальной информацией, и необходимо уделять особое внимание, чтобы сохранить его конфиденциальность. В частности, воздержитесь от добавления файлов json -учетной записи службы в общедоступное управление версиями.
Позволить администратору SDK обнаружить учетную запись обслуживания
Если ваш код развернут в среде, управляемой Google, Admin SDK может попытаться автоматически раскрыть средства для подписи пользовательских токенов:
Если ваш код развернут в стандартной среде App Engine для Java, Python или GO, Admin SDK может использовать службу идентификации приложений, присутствующая в этой среде, чтобы подписать пользовательские токены. Служба службы приложения подписывает данные, используя учетную запись службы, предоставляемую для вашего приложения Google App Engine.
Если ваш код развернут в какой-либо другой управляемой среде (например, Google Cloud Functions, Google Compute Engine), SDK Firebase Admin SDK может автоматически открыть строку идентификатора учетной записи службы с локального сервера Metadata . Затем идентификатор учетной записи Service используется в сочетании с службой IAM для удаленного подписи токенов.
Чтобы использовать эти методы подписания, инициализируйте SDK с помощью учетных данных по умолчанию Google по умолчанию и не указывайте строку идентификатора учетной записи службы:
initializeApp();
FirebaseApp.initializeApp();
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();
Чтобы проверить тот же код локально, загрузите файл JSON Service Account и установите переменную среды GOOGLE_APPLICATION_CREDENTIALS
, чтобы указать на нее.
Если Admin SDK Firebase должен обнаружить строку идентификатора учетной записи службы, она делает это, когда ваш код создает пользовательский токен в первый раз. Результат кэшируется и повторно используется для последующих операций подписания токена. Автоматическое открытое идентификатор учетной записи службы, как правило, является одной из учетных записей служб по умолчанию, предоставленной Google Cloud :
Как и в случае с явно указанными идентификаторами учетной записи службы, идентификаторы учетной записи службы Auto-Discoverd должны иметь разрешение iam.serviceAccounts.signBlob
на создание пользовательского тона для работы. Возможно, вам придется использовать раздел IAM и ADMIN в Google Cloud , чтобы предоставить учетные записи служб по умолчанию необходимые разрешения. См. Раздел «Устранение неполадок» ниже для получения более подробной информации.
Использование идентификатора учетной записи службы
Чтобы поддерживать согласованность между различными частями вашего приложения, вы можете указать идентификатор учетной записи службы, ключи которых будут использоваться для подписи токенов при запуске в среде, управляемой Google. Это может сделать политику IAM проще и безопаснее, и избежать необходимости включать файл JSON Service Account в вашем коде.
Идентификатор учетной записи службы можно найти в консоли Google Cloud или в поле client_email
загруженного файла JSON Service Account. Идентификаторы учетной записи службы-это адреса электронной почты, в которых есть следующий формат: <client-id>@<project-id>.iam.gserviceaccount.com
. Они однозначно идентифицируют учетные записи услуг в Firebase и Google Cloud Projects.
Чтобы создать пользовательские токены, используя отдельный идентификатор учетной записи службы, инициализируйте SDK, как показано ниже:
initializeApp({
serviceAccountId: 'my-client-id@my-project-id.iam.gserviceaccount.com',
});
FirebaseOptions options = FirebaseOptions.builder()
.setCredentials(GoogleCredentials.getApplicationDefault())
.setServiceAccountId("my-client-id@my-project-id.iam.gserviceaccount.com")
.build();
FirebaseApp.initializeApp(options);
options = {
'serviceAccountId': 'my-client-id@my-project-id.iam.gserviceaccount.com',
}
firebase_admin.initialize_app(options=options)
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)
}
FirebaseApp.Create(new AppOptions()
{
Credential = GoogleCredential.GetApplicationDefault(),
ServiceAccountId = "my-client-id@my-project-id.iam.gserviceaccount.com",
});
Идентификаторы учетной записи службы не являются конфиденциальной информацией, и поэтому их экспозиция несущественна. Тем не менее, чтобы подписать пользовательские токены с указанной учетной записью сервисной учетной записи, SDK Admin Firebase должен вызвать удаленную службу. Более того, вы также должны убедиться, что учетная запись службы, которую использует Admin SDK для выполнения этого вызова-обычно {project-name}@appspot.gserviceaccount.com
-имеет разрешение iam.serviceAccounts.signBlob
. См. Раздел «Устранение неполадок» ниже для получения более подробной информации.
Создайте пользовательские токены, используя Admin SDK Firebase
Admin SDK Firebase имеет встроенный метод для создания пользовательских токенов. Как минимум, вам необходимо предоставить uid
, который может быть любой строкой, но должен уникально идентифицировать пользователя или устройство, которое вы аутентифицируете. Эти жетоны истекают через час.
const uid = 'some-uid';
getAuth()
.createCustomToken(uid)
.then((customToken) => {
// Send token back to client
})
.catch((error) => {
console.log('Error creating custom token:', error);
});
String uid = "some-uid";
String customToken = FirebaseAuth.getInstance().createCustomToken(uid);
// Send token back to client
uid = 'some-uid'
custom_token = auth.create_custom_token(uid)
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)
var uid = "some-uid";
string customToken = await FirebaseAuth.DefaultInstance.CreateCustomTokenAsync(uid);
// Send token back to client
Вы также можете указать дополнительные претензии, которые будут включены в пользовательский токен. Например, ниже, в пользовательский токен был добавлен поле premiumAccount
, который будет доступен в объектах auth
/ request.auth
в ваших правилах безопасности:
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);
});
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
uid = 'some-uid'
additional_claims = {
'premiumAccount': True
}
custom_token = auth.create_custom_token(uid, additional_claims)
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)
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
Зарезервированные настраиваемые названия токенов
Войдите в использование пользовательских токенов на клиентах
После создания пользовательского токена вы должны отправить его в приложение для клиента. Клиентское приложение аутентифицируется с пользовательским токеном, вызывая signInWithCustomToken()
:
Цель-C
[[FIRAuth auth] signInWithCustomToken:customToken
completion:^(FIRAuthDataResult * _Nullable authResult,
NSError * _Nullable error) {
// ...
}];
Быстрый
Auth.auth().signIn(withCustomToken: customToken ?? "") { user, error in
// ...
}
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);
}
}
});
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.AuthResult result = task.Result;
Debug.LogFormat("User signed in successfully: {0} ({1})",
result.User.DisplayName, result.User.UserId);
});
firebase::Future<firebase::auth::AuthResult> result =
auth->SignInWithCustomToken(custom_token);
firebase.auth().signInWithCustomToken(token)
.then((userCredential) => {
// Signed in
var user = userCredential.user;
// ...
})
.catch((error) => {
var errorCode = error.code;
var errorMessage = error.message;
// ...
});
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;
// ...
});
Если аутентификация преуспевает, ваш пользователь теперь будет вписан в ваше клиентское приложение с учетной записью, указанной в uid
включенном в пользовательский токен. Если эта учетная запись ранее не существовало, будет создана запись для этого пользователя.
Точно так же, как и с другими методами входа (например, signInWithEmailAndPassword()
и signInWithCredential()
) объект auth
в ваших Realtime Database Security Rules и объект request.auth
в ваших Cloud Storage Security Rules будет заполнен uid
пользователя. В этом случае uid
будет тем, который вы указали при создании пользовательского токена.
{
"rules": {
"adminContent": {
".read": "auth.uid === 'some-uid'"
}
}
}
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";
}
}
}
Если пользовательский токен Cloud Storage дополнительные претензии, их можно ссылаться на объект auth.token
( Firebase Realtime Database ) или request.auth.token
.
{
"rules": {
"premiumContent": {
".read": "auth.token.premiumAccount === true"
}
}
}
service firebase.storage {
match /b/<your-firebase-storage-bucket>/o {
match /premiumContent/{filename} {
allow read, write: if request.auth.token.premiumAccount == true;
}
}
}
Создать пользовательские токены с использованием сторонней библиотеки JWT
Если ваш бэкэнд находится на языке, у которого нет официального SDK Firebase Admin SDK, вы все равно можете вручную создавать пользовательские токены. Во-первых, найдите стороннюю библиотеку JWT для вашего языка. Затем используйте эту библиотеку JWT для Mint A JWT, который включает в себя следующие претензии:
Пользовательские претензии | ||
---|---|---|
alg | Алгоритм | "RS256" |
iss | Эмитент | Адрес электронной почты вашего проекта в сфере услуг |
sub | Предмет | Адрес электронной почты вашего проекта в сфере услуг |
aud | Аудитория | "https://identitytoolkit.googleapis.com/google.identity.identitytoolkit.v1.IdentityToolkit" |
iat | Выпущено в время | Текущее время, за несколько секунд с момента эпохи UNIX |
exp | Срок годности | Время, за несколько секунд после эпохи UNIX, в которой срок действия токена истекает. Это может быть максимум на 3600 секунд позже iat .Примечание. Это контролирует только время, когда истекает сам таковой токен . Но как только вы подписываете пользователя в использовании signInWithCustomToken() , он останется подписанными в устройство до тех пор, пока их сеанс не будет признан недействительным или пользовательским выведением. |
uid | Уникальный идентификатор подписанного пользователя должен быть строкой, от 1 до 128 символов, включительно. Более короткий uid S предлагает лучшую производительность. | |
claims (необязательно) | Необязательные пользовательские претензии на включение в правила безопасности auth / request.auth переменные |
Вот несколько примеров реализаций того, как создавать пользовательские токены на различных языках, которые не поддерживает Admin SDK Firebase Admin SDK:
Использование 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");
}
Использование 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
После создания пользовательского токена отправьте его в свое клиентское приложение для аутентификации с Firebase. Смотрите приведенные выше образцы кода для того, как это сделать.
Поиск неисправностей
В этом разделе изложены некоторые общие проблемы, которые разработчики могут столкнуться при создании пользовательских токенов и как их решить.
IAM API не включен
Если вы указываете идентификатор учетной записи службы для подписи токенов, вы можете получить ошибку, аналогичную следующему:
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.
Admin SDK Firebase использует API IAM для подписи токенов. Эта ошибка указывает на то, что IAM API в настоящее время не включен для вашего проекта Firebase. Откройте ссылку в сообщении об ошибке в веб -браузере и нажмите кнопку «Включить API», чтобы включить ее для вашего проекта.
Сервисная учетная запись не требует разрешений
Если с учетом обслуживания работает Admin SDK Firebase Admin, а также нет разрешения iam.serviceAccounts.signBlob
, вы можете получить сообщение об ошибке, как следующее:
Permission iam.serviceAccounts.signBlob is required to perform this operation on service account projects/-/serviceAccounts/{your-service-account-id}.
Самый простой способ разрешить это-предоставить роль «создателя токена услуг» в рассматриваемой учетной записи, обычно {project-name}@appspot.gserviceaccount.com
- Откройте страницу IAM и Admin в консоли Google Cloud .
- Выберите свой проект и нажмите «Продолжить».
- Нажмите на значок «Редактировать», соответствующий учетной записи службы, которую вы хотите обновить.
- Нажмите «Добавить другую роль».
- Введите «Создатель токена учетной записи службы» в поисковый фильтр и выберите его из результатов.
- Нажмите «Сохранить», чтобы подтвердить грант роли.
Обратитесь к документации IAM для получения более подробной информации об этом процессе или узнайте, как выполнять роли обновления, используя инструменты командной строки GCLOUD.
Не удалось определить учетную запись службы
Если вы получите сообщение об ошибке, аналогичное следующему, Admin SDK Firebase не был должным образом инициализирован.
Failed to determine service account ID. Initialize the SDK with service account credentials or specify a service account ID with iam.serviceAccounts.signBlob permission.
Если вы полагаетесь на SDK для автоматического раскрытия идентификатора учетной записи службы, убедитесь, что код развернут в управляемой среде Google с сервером метаданных. В противном случае, обязательно укажите файл файла JSON или идентификатор службы с учетной записью службы на идентификации SDK инициализации.