Как настроить вход через Google и Apple в Delphi-приложении
Авторизация через Google и Apple позволяет пользователю войти в мобильное или настольное приложение без отдельной регистрации и запоминания нового пароля. Для Delphi-разработчика такая задача включает несколько уровней: настройку провайдеров, открытие страницы входа, получение токенов, передачу данных на сервер и создание локальной сессии.
В приложениях FireMonkey можно использовать единый интерфейс для Android, iOS, Windows и macOS, однако системные требования платформ различаются. Google чаще подключают через OAuth 2.0 и OpenID Connect, а Apple предоставляет собственный Sign in with Apple, обязательный для многих приложений в экосистеме iOS, если в них доступны альтернативные способы входа.
Надёжная схема должна исключать хранение секретных ключей внутри клиента. Delphi-приложение получает временный код или токен, отправляет его на сервер, а сервер проверяет подпись и выпускает собственный токен сессии. Такой подход подходит для PHP-бэкенда, REST API и баз данных, которые могут использоваться в кроссплатформенном проекте.
Как устроен поток авторизации
Клиентское приложение запускает браузер или системное окно авторизации. Пользователь выбирает Google или Apple, подтверждает доступ, после чего провайдер возвращает приложению authorization code либо набор токенов. Для мобильных платформ возврат обычно выполняется через custom URL scheme, universal link или app link.
Безопаснее применять Authorization Code Flow с PKCE. Приложение генерирует случайные значения state и code_verifier, отправляет хеш проверочного значения провайдеру, а после возврата кода подтверждает обмен с помощью исходного code_verifier. Параметр state защищает от подмены ответа и должен проверяться до любой дальнейшей обработки.
После получения кода Delphi-клиент передаёт его собственному API. Сервер обменивает код на токены, проверяет их содержимое, находит или создаёт пользователя в базе данных и возвращает приложению внутреннюю сессию. В результате Google и Apple остаются внешними поставщиками личности, а бизнес-логика проекта контролируется разработчиком.
Настройка приложения Google
В Google Cloud Console нужно создать проект, включить необходимые API и настроить экран согласия OAuth. В нём указываются название приложения, адрес поддержки, домены, логотип и список разрешений. Для базового входа обычно достаточно областей openid, email и profile.
Затем создаются OAuth-клиенты для конкретных платформ. Для Android используется имя пакета и отпечаток SHA-1 или SHA-256 сертификата подписи. Для iOS указываются идентификатор Bundle ID и настройки приложения. Для веб-сервера создаётся отдельный клиент с корректным адресом перенаправления. Важно не смешивать идентификаторы разных платформ.
В Delphi можно открыть authorization URL через IFMX用? Нет необходимости привязываться к конкретному компоненту: подойдут системный браузер, TWebBrowser или специализированная библиотека OAuth 2.0. Для мобильного приложения предпочтителен системный браузер с механизмом безопасного возврата, например ASWebAuthenticationSession на iOS и Custom Tabs на Android.
Подключение Sign in with Apple
В Apple Developer нужно зарегистрировать App ID, включить Sign in with Apple и создать Service ID, если авторизация проходит через веб-сервер. Для обмена authorization code серверу потребуется ключ Sign in with Apple, идентификатор команды, идентификатор клиента и сформированный client secret в формате JWT. Приватный ключ нельзя включать в Delphi-приложение.
Apple возвращает идентификатор пользователя, короткоживущий authorization code и, при первом входе, данные имени и адрес электронной почты. Имя доступно только при первоначальном согласии, поэтому его следует сразу сохранить. Пользователь может скрыть настоящий адрес, и тогда приложение получит адрес вида privaterelay.appleid.com.
На стороне iOS необходимо добавить capability Sign in with Apple и корректно настроить redirect URI. Для нативного сценария можно использовать системный SDK через Delphi bridge, Objective-C bridge или готовую библиотеку. Универсальный вариант через браузер проще поддерживать, но требует аккуратной настройки возврата в приложение и серверного обмена кодом.
| Параметр | Apple | |
|---|---|---|
| Основной протокол | OAuth 2.0 и OpenID Connect | OAuth 2.0 с идентификатором Apple |
| Идентификатор пользователя | Поле sub в ID token |
Поле sub в ID token |
| Почта | Обычно доступна при согласии | Может быть скрыта через relay-адрес |
| Имя | Может возвращаться при входе | Обычно доступно только один раз |
| Проверка токена | Подпись Google и параметры aud, iss, exp |
Подпись Apple и параметры aud, iss, exp |
| Секрет клиента | Хранится на сервере | JWT client secret создаётся сервером |
| Особенности платформ | Отпечатки Android и OAuth-клиенты | Capability, Service ID и приватный ключ |
Реализация потока в Delphi
Для сетевого обмена можно использовать TNetHTTPClient, THTTPClient или собственный REST-слой. При формировании URL необходимо кодировать все параметры: client_id, redirect_uri, scope, state, nonce и code_challenge. Ручная склейка строк без URL-кодирования часто приводит к ошибкам с символами +, / и пробелами.
После возврата из браузера приложение получает URI и извлекает из него параметры code, state и error. Если присутствует ошибка, пользователю нужно показать понятное сообщение, а не передавать необработанный ответ в серверный API. Полученный state сравнивается со значением, сохранённым перед запуском авторизации.
Для разных платформ удобно создать единый класс, например ISocialAuthenticator, с методами запуска входа, обработки redirect URI и завершения сессии. Реализации Android и iOS могут использовать собственные системные механизмы, тогда как Windows и macOS способны работать через браузер и зарегистрированный URL-протокол. Такое разделение сохраняет общий код FireMonkey чистым.
Не следует считать сам факт возврата email доказательством личности. Клиент должен передавать на сервер код авторизации, а не доверять полученным из браузера полям профиля. Если провайдер возвращает ID token напрямую, его также нужно проверять на серверной стороне.
Проверка токенов на сервере
Сервер получает код от Delphi-приложения и отправляет запрос на token endpoint соответствующего провайдера по HTTPS. Для Google это endpoint Google OAuth, для Apple — адрес авторизации Apple. Ответ может содержать access_token, id_token, refresh_token и срок действия. Парсить JWT недостаточно: необходимо проверить криптографическую подпись и стандартные claims.
Проверяются издатель iss, аудитория aud, время окончания exp, время выпуска iat, а для OIDC-сценария также nonce. Публичные ключи Google и Apple публикуются через JWKS endpoints и могут кэшироваться сервером с периодическим обновлением. Если ключ сменился, сервер должен получить свежий набор, а не навсегда использовать старую копию.
У пользователя в базе лучше хранить пару provider и provider_user_id, например google плюс значение sub или apple плюс значение sub. Электронная почта не должна быть единственным ключом: она может измениться, быть скрыта или совпасть с уже существующей записью. Объединение аккаунтов следует выполнять только после дополнительного подтверждения владельца.
Собственная сессия приложения
После успешной проверки сервер создаёт внутреннюю учётную запись или связывает внешний профиль с существующей. Клиент получает собственный access token с коротким сроком действия и, при необходимости, refresh token. Сессионные данные нужно хранить в Android Keystore, iOS Keychain, macOS Keychain или защищённом хранилище Windows, а не в обычном текстовом файле.
При каждом обращении к API сервер проверяет собственный токен и права пользователя. Внешний access token Google или Apple не стоит использовать как постоянный пропуск к бизнес-методам. Его назначение — подтвердить личность во время входа или выполнить ограниченное действие, если это предусмотрено архитектурой.
Выход из приложения должен удалять локальные токены и сбрасывать состояние пользователя. При отзыве разрешения, смене пароля или истечении внешней сессии сервер может потребовать повторную авторизацию. Для чувствительных операций полезно запрашивать свежую проверку личности и не полагаться на старую сессию.
Тестирование и защита интеграции
Проверяйте вход на реальных устройствах Android и iOS, а также на каждой настольной платформе, где распространяется приложение. Эмуляторы не всегда корректно воспроизводят возврат из системного браузера, работу Keychain или поведение Universal Links. Отдельно тестируются отмена входа, отсутствие сети, повторный запуск приложения и просроченный authorization code.
Redirect URI должен совпадать с зарегистрированным символ в символ, включая схему, регистр, путь и завершающий слеш. На мобильных устройствах custom scheme может быть перехвачена другим приложением, поэтому для важных сценариев предпочтительны verified app links или universal links. Также нужно включить проверку TLS и не разрешать небезопасные HTTP-соединения в рабочей сборке.
Секреты Google и Apple хранятся в переменных окружения или защищённом хранилище сервера. В журнал нельзя записывать access token, refresh token, authorization code и полный ID token. Полезно вести обезличенные события: начало входа, успешную проверку, причину отказа и идентификатор внутренней сессии.
Перед публикацией следует проверить требования Google Play и App Store, включая правило Apple о доступности Sign in with Apple рядом с альтернативными социальными способами входа. Также нужно подготовить политику конфиденциальности, объяснить обработку адресов relay-почты и предоставить пользователю возможность удалить аккаунт и связанные данные.