С помощью Firebase Authentication можно разрешить пользователям выполнять аутентификацию в Firebase, используя адреса электронной почты и пароли, а также управлять аккаунтами на основе паролей в приложении.
Подготовка
- Добавьте Firebase в свой проект C++.
- Если вы ещё не подключили приложение к проекту Firebase, сделайте это в консоли Firebase.
-
Включите в проекте Firebase вход с адресом электронной почты и паролем:
- В консоли Firebase выберите Безопасность > Аутентификация.
- На вкладке Sign-in method (Способ входа) включите поставщика Email/password (Электронная почта/пароль).
- Нажмите Сохранить.
Как получить доступ к курсу firebase::auth::Auth
Класс Auth – это шлюз для всех вызовов API.
- Добавьте файлы заголовков Auth и App:
#include <cassert> #include <cstdint> #include "firebase/app.h" #include "firebase/auth.h"
- В коде инициализации создайте класс
firebase::App.#if defined(__ANDROID__) firebase::App* app = firebase::App::Create(firebase::AppOptions(), my_jni_env, my_activity); #else firebase::App* app = firebase::App::Create(firebase::AppOptions()); #endif // defined(__ANDROID__)
- Получите класс
firebase::auth::Authдля вашегоfirebase::App. МеждуAppиAuthсуществует однозначное соответствие.firebase::auth::Auth* auth = firebase::auth::Auth::GetAuth(app);
Как создать аккаунт с паролем
Чтобы создать новый пользовательский аккаунт с паролем, выполните следующие действия в коде для входа в приложение:
- Когда новый пользователь регистрируется с помощью формы в вашем приложении, выполните все необходимые шаги для проверки нового аккаунта, например убедитесь, что пароль введен правильно и соответствует требованиям к сложности.
- Создайте новый аккаунт, передав адрес электронной почты и пароль нового пользователя в
Auth::CreateUserWithEmailAndPassword:firebase::Future<firebase::auth::AuthResult> result = auth->CreateUserWithEmailAndPassword(email, password);
- Если в вашей программе есть цикл обновления, который выполняется регулярно (например, 30 или 60 раз в секунду), вы можете проверять результаты один раз за обновление с помощью
Auth::CreateUserWithEmailAndPasswordLastResult: Если ваша программа управляется событиями, вы можете зарегистрировать обратный вызов в объекте Future.firebase::Future<firebase::auth::AuthResult> result = auth->CreateUserWithEmailAndPasswordLastResult(); if (result.status() == firebase::kFutureStatusComplete) { if (result.error() == firebase::auth::kAuthErrorNone) { const firebase::auth::AuthResult auth_result = *result.result(); printf("Create user succeeded for email %s\n", auth_result.user.email().c_str()); } else { printf("Created user failed with error '%s'\n", result.error_message()); } }
Как войти в аккаунт с помощью адреса электронной почты и пароля
Шаги для входа пользователя с паролем похожи на шаги для создания нового аккаунта. В функции входа в приложение сделайте следующее:
- Когда пользователь входит в ваше приложение, передайте его адрес электронной почты и пароль в
firebase::auth::Auth::SignInWithEmailAndPassword:firebase::Future<firebase::auth::AuthResult> result = auth->SignInWithEmailAndPassword(email, password);
- Если в вашей программе есть цикл обновления, который выполняется регулярно (например, 30 или 60 раз в секунду), вы можете проверять результаты один раз за обновление с помощью
Auth::SignInWithEmailAndPasswordLastResult: Если ваша программа управляется событиями, вы можете зарегистрировать обратный вызов в объекте Future.firebase::Future<firebase::auth::AuthResult> result = auth->SignInWithEmailAndPasswordLastResult(); if (result.status() == firebase::kFutureStatusComplete) { if (result.error() == firebase::auth::kAuthErrorNone) { const firebase::auth::AuthResult auth_result = *result.result(); printf("Sign in succeeded for email %s\n", auth_result.user.email().c_str()); } else { printf("Sign in failed with error '%s'\n", result.error_message()); } }
Как зарегистрировать обратный вызов в Future
В некоторых программах естьUpdate функции, которые вызываются 30 или 60 раз в секунду.
Например, многие игры работают по этой модели. Эти программы могут вызывать функции LastResult для опроса асинхронных вызовов.
Однако если ваша программа управляется событиями, вам может быть удобнее зарегистрировать функции обратного вызова.
Функция обратного вызова вызывается после завершения Future.
void OnCreateCallback(const firebase::Future<firebase::auth::User*>& result, void* user_data) { // The callback is called when the Future enters the `complete` state. assert(result.status() == firebase::kFutureStatusComplete); // Use `user_data` to pass-in program context, if you like. MyProgramContext* program_context = static_cast<MyProgramContext*>(user_data); // Important to handle both success and failure situations. if (result.error() == firebase::auth::kAuthErrorNone) { firebase::auth::User* user = *result.result(); printf("Create user succeeded for email %s\n", user->email().c_str()); // Perform other actions on User, if you like. firebase::auth::User::UserProfile profile; profile.display_name = program_context->display_name; user->UpdateUserProfile(profile); } else { printf("Created user failed with error '%s'\n", result.error_message()); } } void CreateUser(firebase::auth::Auth* auth) { // Callbacks work the same for any firebase::Future. firebase::Future<firebase::auth::AuthResult> result = auth->CreateUserWithEmailAndPasswordLastResult(); // `&my_program_context` is passed verbatim to OnCreateCallback(). result.OnCompletion(OnCreateCallback, &my_program_context); }
void CreateUserUsingLambda(firebase::auth::Auth* auth) { // Callbacks work the same for any firebase::Future. firebase::Future<firebase::auth::AuthResult> result = auth->CreateUserWithEmailAndPasswordLastResult(); // The lambda has the same signature as the callback function. result.OnCompletion( [](const firebase::Future<firebase::auth::User*>& result, void* user_data) { // `user_data` is the same as &my_program_context, below. // Note that we can't capture this value in the [] because std::function // is not supported by our minimum compiler spec (which is pre C++11). MyProgramContext* program_context = static_cast<MyProgramContext*>(user_data); // Process create user result... (void)program_context; }, &my_program_context); }
Рекомендуется: задайте правила для паролей
Вы можете повысить безопасность аккаунта, введя обязательные критерии сложности паролей.
Чтобы настроить правила в отношении паролей для проекта, откройте раздел Правила в отношении паролей на вкладке Безопасность > Аутентификация > Настройки консоли Firebase:
Firebase Authentication поддерживает следующие требования к паролям:
Требуется строчная буква
Требуется заглавная буква
Требуется цифра
Требуется символ, не являющийся буквой или цифрой
К символам, не являющимся буквами или цифрами, относятся:
^ $ * . [ ] { } ( ) ? " ! @ # % & / \ , > < ' : ; | _ ~Минимальная длина пароля (от 6 до 30 символов; по умолчанию – 6)
Максимальная длина пароля (максимум 4096 символов).
Применение правил в отношении паролей можно включить в двух режимах:
Требовать. Пользователь не может зарегистрироваться, пока не изменит пароль на соответствующий критериям.
Уведомление. Пользователь может зарегистрироваться с паролем, не соответствующим требованиям. В этом режиме вам нужно проверить, соответствует ли пароль пользователя правилам на стороне клиента, и предложить пользователю обновить пароль, если он не соответствует правилам.
Новые пользователи всегда должны выбирать пароль, соответствующий вашим правилам.
Если у вас есть активные пользователи, мы рекомендуем не включать принудительное обновление при входе, если вы не планируете блокировать доступ пользователям, чьи пароли не соответствуют правилам. Вместо этого используйте режим уведомлений, который позволяет пользователям входить в систему с текущими паролями и сообщает им о требованиях, которым не соответствует их пароль.
Рекомендуется включить защиту от перечисления адресов электронной почты
Некоторые методы Firebase Authentication, которые принимают адреса электронной почты в качестве параметров, выдают определенные ошибки, если адрес электронной почты не зарегистрирован, когда он должен быть зарегистрирован (например, при входе с использованием адреса электронной почты и пароля), или зарегистрирован, когда он должен быть неиспользованным (например, при изменении адреса электронной почты пользователя). Это может быть полезно для предоставления пользователям конкретных рекомендаций, но злоумышленники могут использовать эту функцию, чтобы узнавать адреса электронной почты, зарегистрированные вашими пользователями.
Чтобы снизить этот риск, рекомендуем включить защиту от перечисления адресов электронной почты для вашего проекта. Проверить эту настройку можно в консоли Firebase: выберите Безопасность > Аутентификация > вкладка Настройки и нажмите Действия пользователя.
Обратите внимание, что при включении этой функции меняется поведение при регистрации ошибок для Firebase Authentication, поэтому убедитесь, что ваше приложение не полагается на более конкретные ошибки.
Дальнейшие действия
После первого входа пользователя создается новый аккаунт, связанный с учетными данными, которые он использовал (именем пользователя и паролем, номером телефона или информацией поставщика услуг аутентификации). Этот новый аккаунт хранится в проекте Firebase и позволяет идентифицировать пользователя во всех приложениях проекта независимо от того, как он вошел в аккаунт.
-
В своих приложениях вы можете получить основную информацию профиля пользователя из объекта
firebase::auth::User:firebase::auth::User user = auth->current_user(); if (user.is_valid()) { std::string name = user.display_name(); std::string email = user.email(); std::string photo_url = user.photo_url(); // The user's ID, unique to the Firebase project. // Do NOT use this value to authenticate with your backend server, // if you have one. Use firebase::auth::User::Token() instead. std::string uid = user.uid(); }
В Firebase Realtime Database и Cloud Storage правилах безопасности можно получить уникальный идентификатор пользователя, выполнившего вход, из переменной
authи использовать его, чтобы контролировать, к каким данным у пользователя есть доступ.
Вы можете разрешить пользователям входить в ваше приложение, используя несколько поставщиков услуг аутентификации, связав учетные данные поставщика услуг аутентификации с существующим аккаунтом пользователя.
Чтобы выйти из аккаунта пользователя, вызовите функцию
SignOut():
auth->SignOut();