Аутентификация: сгенерированный код
Включить аутентификацию во FlutterFlow — дело нескольких кликов: выбрать тип в настройках и повесить действие на кнопку входа. Но за этим стоит заметный объём сгенерированного кода. Разберём, из чего он состоит: сначала общая структура, потом различия между собственной аутентификацией и Firebase/Supabase.
Структура файлов
При включении собственной аутентификации в проекте появляются такие файлы:
lib/
auth/
custom_auth/
auth_util.dart
custom_auth_manager.dart
custom_auth_user_provider.dart
Для Firebase набор шире:
lib/
auth/
firebase_auth/
auth_util.dart
email_auth.dart (и файлы других провайдеров)
firebase_auth_manager.dart
firebase_user_provider.dart
auth_manager.dart
base_auth_user_provider.dart
Ниже разбирается код именно собственной аутентификации. Как подключить её к приложению, описано в разделе Собственная аутентификация.
Custom Auth Manager
Центральный класс сгенерированной системы — CustomAuthManager. Он хранит атрибуты сессии — authenticationToken, refreshToken, tokenExpiration — и данные пользователя: uid, userData.
Его основные методы:
signIn()— вход пользователя.signOut()— выход.updateAuthUserData()— обновление данных сессии и пользователя.persistAuthData()— сохранение данных между запусками, чтобы вход не слетал.
Второй важный файл — custom_auth_user_provider.dart. В нём объявлен класс <ProjectName>AuthUser, описывающий состояние вошедшего пользователя. Поток объекта пользователя построен на BehaviorSubject из пакета rxdart: изначально в нём лежит объект «пользователь не вошёл», а каждое действие входа или выхода отправляет в поток новое состояние. Всё, что зависит от статуса авторизации, обновляется немедленно.
В custom_auth_manager.dart объявлена переменная currentUser — экземпляр <ProjectName>AuthUser. Это единая точка доступа к данным текущего пользователя из любого места приложения. Свойство loggedIn коротко отвечает на вопрос, вошёл ли пользователь.
Инициализация
В файле auth_util лежит синглтон CustomAuthManager:
final _authManager = CustomAuthManager();
CustomAuthManager get authManager => _authManager;
Метод authManager.initialize() вызывается в main() до runApp. Он создаёт экземпляр SharedPreferences под authToken, refreshToken и остальные значения, а заодно отвечает за истечение срока токенов — включая автоматический выход, когда они протухли.
Инициализация происходит только потому, что в настройках собственной аутентификации включена опция Persist Auth Sessions.

Здесь же лежат геттеры для идентификатора пользователя, токена и прочих данных — обращаться к ним из кода приложения удобно.
Как работает вход
Когда пользователь нажимает кнопку входа, запускается цепочка операций.
Метод signIn внутри вызывает _updateCurrentUser из CustomAuthManager. Тот принимает authenticationToken, refreshToken, tokenExpiration, authUid и userData и записывает их в свойства класса — так сохраняются данные текущей сессии.
Что такое токен доступа, токен обновления и срок действия токена — в разделе Токены.
Дальше в поток пользователя отправляется новый объект с loggedIn, равным true, вместе с authUid и userData. Все подписчики потока узнают, что пользователь вошёл.
Затем вызывается persistAuthData — токены, срок их действия и идентификатор пользователя сохраняются для следующих запусков.
В конце вызывается context.goNamedAuth('AuthPage', context.mounted); — переход на страницу, указанную в настройках аутентификации как страница вошедшего пользователя.