Вход через внешние сервисы
Пользователи могут входить на сайт через GitHub, Google, VK и Яндекс. Список не закрыт: любой из них выключается в админке, а новые добавляются модулями (см. раздел для разработчиков ниже).
Это не отдельный способ аутентификации: флоу заканчивается обычной сессией, той же самой, что и вход по паролю. Дальше человек ходит по сайту с обычной кукой jc_auth, а привязка живёт в таблице user_identities.
Про VK
VK подключается через VK ID (id.vk.com, OAuth 2.1), а не через классический oauth.vk.com: приложение, зарегистрированное сейчас, классический флоу проходить не будет — VK ответит Security Error без пояснений. У VK ID три особенности, все обязательные: PKCE, device_id из callback в запросе токена и профиль из /oauth2/user_info (ни в токене, ни в users.get адреса нет).
Настройка
Экран /admin/auth/providers (право admin.settings.manage):
Client IDиClient secretприложения, зарегистрированного у провайдера;переключатель «Включён» — сервис показывается на экранах входа, только если включён и оба ключа заполнены;
адрес возврата (Callback URL) — его нужно скопировать в настройки приложения у провайдера.
Ключи сохраняются в config/autoload/auth.local.php — этот файл в .gitignore, рядом с паролем БД. Не переносите их в auth.global.php: он попадает в репозиторий.
Сохранённый секрет никогда не отправляется обратно в браузер: поле пустое, а заполнять его нужно только чтобы заменить.
Что происходит при входе
Аккаунт уже привязан — вход,
last_login_atобновляется, в журнал пишетсяoauth.login.Адрес совпал с существующим аккаунтом. Автоматическая привязка допустима, только если провайдер подтвердил адрес и адрес подтверждён на сайте. Иначе — отказ с предложением войти по паролю и привязать сервис вручную. Это защита от захвата аккаунта: иначе достаточно зарегистрироваться где-то с чужим адресом.
Никого не нашли — экран «Завершение регистрации»: логин и адрес. Он нужен всегда: VK может не отдать адрес вовсе, а отображаемое имя почти никогда не годится в качестве уникального логина.
Регистрация закрыта (у роли
guestнет праваregistration.register) — существующие аккаунты через провайдер входят, новые не создаются.
Созданный так аккаунт не имеет пароля. Это не пустой пароль: хэшер отказывает сразу, поэтому войти «пустым паролем» в такой аккаунт нельзя.
Привязанные аккаунты
Раздел профиля /profile/accounts: список привязанных сервисов, кнопка «Привязать другой сервис» и отвязка.
Последний способ входа отвязать нельзя. Если пароля нет, а сервис один — отвязка запрещена: восстанавливать было бы нечего, восстановление пароля работает только там, где пароль есть.
Сервис, чей модуль удалили, показывается в списке как «Недоступен» — привязку всё ещё можно снять, а строки в БД при выключении сервиса не удаляются, чтобы включение обратно ничего не потеряло.
Журнал
В журнал входов пишутся oauth.login, oauth.register, oauth.linked и oauth.unlinked — с ключом провайдера в контексте.
Безопасность round trip
state одноразовый, живёт 10 минут и хранится в PHP-сессии; поверх него — PKCE. Без этого callback можно воспроизвести: злоумышленник начинает флоу со своим аккаунтом у провайдера и подсовывает ссылку жертве, после чего его аккаунт оказывается привязан к чужому.
Маршрут /auth/{provider}/callback освобождён от CSRF-проверки (провайдер не носит наш токен) — именно state и PKCE его и заменяют.
Последнее обновление
Это было полезно?