Перейти к содержанию

Аутентификация

Эндпоинты для входа и выхода по JWT, сброса пароля, проверки двухфакторной аутентификации, первичной настройки, политики паролей, принятия приглашения, капчи при входе, входа через SSO и получения текущей сессии. Всё под /auth/ публично (аутентификация не требуется). GET /me требует аутентифицированной сессии.

Получение токена

POST /auth/token

Вход по имени пользователя и паролю: в ответ приходят JWT-токен доступа и токен обновления, а также объект user с профилем учётной записи, вычисленными разрешениями и состоянием демо-режима (те же данные, что возвращает GET /me). Если в учётной записи включена 2FA, вместо токенов возвращается запрос на подтверждение 2FA (см. ниже); завершите вход через POST /auth/2fa/verify. Учётная запись должна быть суперадминистратором либо иметь admin.login или api.access и не должна быть отключена. Это публичный эндпоинт, предварительная аутентификация не требуется. Частота запросов ограничивается для каждого имени пользователя через плагин Login.

Параметры

Имя Тип Обязательный Описание
username string Да Имя пользователя учётной записи
password string Да Пароль учётной записи
captcha_token string Нет Решённая капча. Требуется, только когда капча входа сайта охватывает процесс входа (см. GET /auth/captcha). Для встроенного провайдера cap это токен из POST /auth/captcha/redeem; для Turnstile или reCAPTCHA — токен ответа виджета.

Запрос

{"username": "admin", "password": "password"}

Ответ

{"data": {"access_token": "eyJ...", "refresh_token": "eyJ...", "token_type": "Bearer", "expires_in": 3600, "user": {"username": "admin", "fullname": "Site Admin", "email": "admin@example.com", "avatar_url": null, "super_admin": true, "access": {"api": {"super": true}, "site": {"login": true}}, "content_editor": "", "demo_mode": {"enabled": false, "writable": [], "reset_interval": 30, "seconds_until_reset": null}}}}

Коды ответов

Код Описание
200 Токены созданы, либо возвращён запрос 2FA, когда в учётной записи включена 2FA.
401 Неверные учётные данные
403 У учётной записи нет доступа к API или к входу в админку, либо она отключена.
422 Отсутствует имя пользователя или пароль, либо капча отсутствовала или не прошла проверку.
429 Слишком много попыток входа для этого имени пользователя.

Когда в учётной записи включена 2FA, пароль проверяется, но токены не выдаются. Ответ по-прежнему 200, с кратковременным токеном запроса (действует 5 минут), который нужно отправить на POST /auth/2fa/verify вместе с текущим кодом:

{"data": {"requires_2fa": true, "challenge_token": "eyJ...", "expires_in": 300, "token_type": "Challenge"}}

Обновление токена

POST /auth/refresh

Обновляет истёкший токен доступа с помощью действующего токена обновления. Отправленный токен обновления отзывается (ротация токенов), а в ответ приходит новая пара токенов с тем же объектом user, что возвращает POST /auth/token. Это публичный эндпоинт, предварительная аутентификация не требуется.

Параметры

Имя Тип Обязательный Описание
refresh_token string Да Действующий токен обновления, полученный от эндпоинта токенов

Запрос

{"refresh_token": "eyJ..."}

Ответ

{"data": {"access_token": "eyJ...", "refresh_token": "eyJ...", "token_type": "Bearer", "expires_in": 3600, "user": {"username": "admin", "fullname": "Site Admin", "email": "admin@example.com", "avatar_url": null, "super_admin": true, "access": {"api": {"super": true}, "site": {"login": true}}, "content_editor": "", "demo_mode": {"enabled": false, "writable": [], "reset_interval": 30, "seconds_until_reset": null}}}}

Коды ответов

Код Описание
200 Новые токены созданы
401 Недействительный или истёкший токен обновления
403 Учётная запись отключена.
422 Отсутствует поле refresh_token.

Отзыв токена

POST /auth/revoke

Отзывает токен обновления (явный выход из системы). Если запрос также несёт токен доступа (X-API-Token или Authorization: Bearer), этот токен доступа тоже отзывается, поэтому текущая сессия завершается немедленно. Если токен обновления ещё действителен, его пользователь записывается для события onApiUserLogout. Всегда возвращает 204, даже если токен уже был недействителен, поэтому отзыв идемпотентен.

Параметры

Имя Тип Обязательный Описание
refresh_token string Да Токен обновления, который нужно аннулировать (поле тела запроса).

Запрос

{"refresh_token": "eyJ..."}

Коды ответов

Код Описание
204 Токен отозван (или уже был недействителен).
422 Отсутствует поле refresh_token.

Проверка 2FA

POST /auth/2fa/verify

Обменивает токен запроса 2FA вместе с кодом TOTP на полную пару токенов. Токен запроса приходит из /auth/token (или обмена SSO), когда тот отвечает requires_2fa: true. Токен запроса одноразовый и истекает через 5 минут. Ответ несёт тот же объект user, что и /auth/token. При успехе вызывается onApiUserLogin с method: 2fa. Использует тот же ограничитель частоты входа, что и /auth/token.

Параметры

Имя Тип Обязательный Описание
challenge_token string Да Кратковременный токен запроса, возвращённый из /auth/token.
code string Да 6-значный код TOTP из приложения-аутентификатора пользователя.

Запрос

{"challenge_token": "eyJ...", "code": "123456"}

Ответ

{"data": {"access_token": "eyJ...", "refresh_token": "eyJ...", "token_type": "Bearer", "expires_in": 3600, "user": {"username": "admin", "fullname": "Site Admin", "email": "admin@example.com", "avatar_url": null, "super_admin": true, "access": {"api": {"super": true}, "site": {"login": true}}, "content_editor": "", "demo_mode": {"enabled": false, "writable": [], "reset_interval": 30, "seconds_until_reset": null}}}}

Коды ответов

Код Описание
200 Проверка прошла; выдана пара токенов.
401 Недействительный или истёкший токен запроса, либо неверный код 2FA.
403 Учётная запись отключена или поддержка 2FA недоступна на сервере.
422 Отсутствует challenge_token или code.
429 Слишком много неудачных попыток; частота ограничена.

Забыли пароль

POST /auth/forgot-password

Запрашивает письмо для сброса пароля. Всегда возвращает нейтральное сообщение об успехе независимо от того, соответствует ли адрес какой-либо учётной записи, — это предотвращает перебор учётных записей. Частота ограничивается для каждого пользователя через корзину pw_resets плагина Login. Требуются настроенные плагины Email и Login. Ссылка для сброса указывает на собственный маршрут админки /reset и действует 24 часа. Когда капча входа сайта охватывает процесс восстановления пароля, требуется решённый captcha_token.

Параметры

Имя Тип Обязательный Описание
email string Да Адрес электронной почты учётной записи для сброса.
admin_base_url string Нет Источник и базовый путь вызывающего клиента Admin2 (например, https://my-site.example/admin). Используется для построения ссылки сброса в письме. Должен быть URL http/https, чей источник совпадает с источником сайта или указан в cors.origins API; иначе он игнорируется. Откатывается к заголовкам Referer / Origin (с той же проверкой источника), затем к собственному корневому URL Grav.
captcha_token string Нет Решённая капча. Требуется, только когда капча входа сайта охватывает этот процесс (см. GET /auth/captcha).

Запрос

{"email": "admin@my-site.example", "admin_base_url": "https://my-site.example/admin"}

Ответ

{"data": {"message": "If an account exists for that email, a reset link has been sent."}}

Коды ответов

Код Описание
200 Запрос принят (нейтральный ответ независимо от совпадения).
422 Отсутствует поле email, либо капча отсутствовала или не прошла проверку.
429 Превышено ограничение частоты для этого пользователя.

Сброс пароля

POST /auth/reset-password

Завершает сброс пароля с помощью токена из письма для сброса. Все ошибки ссылки возвращают одно и то же расплывчатое сообщение, чтобы перебор токенов не мог отличить неверного пользователя от неверного или истёкшего токена. После успешной проверки ссылки новый пароль должен соответствовать политике паролей сайта (system.pwd_regex, либо не менее 8 символов, когда она не задана; см. GET /auth/password-policy); несоответствие политике называет поле password и оставляет ссылку пригодной для повторной попытки. При успехе все токены доступа и обновления, выданные учётной записи до сброса, перестают работать. Частота ограничивается для каждого имени пользователя. При успехе вызывается onApiPasswordReset.

Параметры

Имя Тип Обязательный Описание
username string Да Имя пользователя учётной записи, для которой выполняется сброс.
token string Да Токен сброса из ссылки в письме.
password string Да Новый пароль. Должен соответствовать политике паролей сайта.

Запрос

{"username": "admin", "token": "abc123...", "password": "N3w-Pa$$w0rd"}

Ответ

{"data": {"message": "Password reset successfully."}}

Коды ответов

Код Описание
200 Пароль обновлён.
422 Отсутствуют обязательные поля, недействительная или истёкшая ссылка сброса, либо новый пароль не соответствует политике паролей.
429 Слишком много попыток; частота ограничена.

Состояние настройки

GET /auth/setup

Проверяет, требуется ли для экземпляра первичная настройка. Возвращает setup_required: true, только когда user/accounts/ пуста. Также возвращает password_policy (тот же объект, что и GET /auth/password-policy), чтобы экран настройки мог проверить пароль без второго запроса. Admin2 опрашивает его при загрузке, чтобы решить, показывать мастер настройки или экран входа. Публичный (аутентификация не требуется).

Ответ

{"data": {"setup_required": true, "password_policy": {"regex": "", "min_length": 8, "rules": [{"id": "length", "label": "At least 8 characters", "pattern": ".{8,}"}]}}}

Коды ответов

Код Описание
200 Состояние успешно возвращено.

Создание первого пользователя

POST /auth/setup

Одноразовая первичная настройка — создаёт начальную учётную запись суперадминистратора на свежей установке Grav 2.0. Активна, только пока user/accounts/ пуста; после этого возвращает 409. По умолчанию выдаёт api.super и site.login (а не admin.super), чтобы учётная запись имела полномочия API, не подразумевая полномочий классической админки. Вызывает onApiUserCreated и onApiSetupComplete, затем выдаёт пару токенов входа (с тем же объектом user, что возвращает POST /auth/token), чтобы клиент мог сразу перейти к панели управления. Публичный (аутентификация не требуется), частота ограничивается по IP. Когда капча входа сайта охватывает процесс настройки, требуется решённый captcha_token.

Параметры

Имя Тип Обязательный Описание
username string Да Имя пользователя (3–64 символа). Не может начинаться с точки или содержать .., а также не может содержать \ / ? * : ; { } или перевод строки.
password string Да Пароль. Должен соответствовать system.pwd_regex либо содержать не менее 8 символов, когда регулярное выражение не задано (см. GET /auth/password-policy).
email string Да Действительный адрес электронной почты.
fullname string Нет Отображаемое имя учётной записи (по умолчанию — имя пользователя).
title string Нет Должность пользователя (по умолчанию «Administrator»).
captcha_token string Нет Решённая капча. Требуется, только когда капча входа сайта охватывает процесс настройки (см. GET /auth/captcha).

Запрос

{"username": "admin", "password": "a-good-secret", "email": "admin@example.com", "fullname": "Site Admin"}

Ответ

{"data": {"access_token": "eyJ...", "refresh_token": "eyJ...", "token_type": "Bearer", "expires_in": 3600, "user": {"username": "admin", "fullname": "Site Admin", "email": "admin@example.com", "avatar_url": null, "super_admin": true, "access": {"api": {"super": true}, "site": {"login": true}}, "content_editor": "", "demo_mode": {"enabled": false, "writable": [], "reset_interval": 30, "seconds_until_reset": null}}}}

Коды ответов

Код Описание
200 Учётная запись создана; выдана пара токенов.
409 Настройка уже завершена.
422 Ошибка валидации (отсутствуют поля, неверный формат имени пользователя, неверный адрес электронной почты, пароль не соответствует политике, либо капча отсутствовала или не прошла проверку).
429 Слишком много попыток настройки с этого IP.

Получение текущего пользователя

GET /me

Возвращает профиль аутентифицированного пользователя и вычисленные разрешения. Admin2 вызывает его при каждой загрузке, чтобы инициализировать интерфейс текущей личностью, картой доступа, состоянием демо-режима, работающей версией ядра Grav и версией активного плагина админки. Поля профиля — тот же объект user, что возвращают эндпоинты входа.

Ответ

{"data": {"username": "admin", "fullname": "Site Admin", "email": "admin@example.com", "avatar_url": "/user/accounts/avatars/admin.png", "super_admin": true, "access": {"api": {"access": true, "super": true}, "site": {"login": true}}, "content_editor": "", "demo_mode": {"enabled": false, "writable": [], "reset_interval": 30, "seconds_until_reset": null}, "grav_version": "2.0.0-beta.1", "admin_version": "3.0.0-beta.1"}}

Коды ответов

Код Описание
200 Профиль возвращён.
401 Не авторизован.
403 У пользователя нет api.access.

Ответ содержит:

  • access — полностью вычисленная карта разрешений (унаследованные + прямые), а не необработанный YAML. Используйте её вместо повторного вывода разрешений на клиенте.
  • demo_mode: является ли учётная запись демо-учётной (access.api.demo). Для демо-учётной записи writable перечисляет пути, в которые ей всё ещё можно писать, а seconds_until_reset отсчитывает время до следующего сброса демо-контента; обычная учётная запись получает writable: [] и seconds_until_reset: null. reset_interval (в минутах) присутствует всегда.
  • grav_version — значение GRAV_VERSION на сервере.
  • admin_version — версия включённого плагина админки (сначала проверяется admin2, затем admin), прочитанная из его blueprints.yaml. null, если ни один не включён.
  • content_editor — предпочтительный редактор контента пользователя (пустая строка, если не задан).

Политика паролей

GET /auth/password-policy

Возвращает политику паролей сайта, чтобы формы настройки, сброса пароля, приглашения и пользователя могли проверять пароль по мере ввода. regex — это system.pwd_regex без изменений. rules — контрольный список: берётся из system.pwd_rules, когда он задан, иначе разбирается из регулярного выражения (длина, цифра, строчная буква, заглавная буква, символ). Когда pwd_regex не задан, API всё равно требует не менее 8 символов, поэтому ответ сообщает min_length: 8 и одно правило длины. Та же политика применяется при настройке, принятии приглашения, сбросе пароля и создании и обновлении пользователя. Публичный (аутентификация не требуется).

Ответ

{"data": {"regex": "(?=.*\\d)(?=.*[a-z])(?=.*[A-Z]).{8,}", "min_length": 8, "rules": [{"id": "length", "label": "At least 8 characters", "pattern": ".{8,}"}, {"id": "digit", "label": "At least one number", "pattern": "\\d"}, {"id": "lowercase", "label": "At least one lowercase letter", "pattern": "[a-z]"}, {"id": "uppercase", "label": "At least one uppercase letter", "pattern": "[A-Z]"}]}}

Коды ответов

Код Описание
200 Политика возвращена.

Когда system.pwd_regex не задан, ответ такой:

{"data": {"regex": "", "min_length": 8, "rules": [{"id": "length", "label": "At least 8 characters", "pattern": ".{8,}"}]}}

Проверка приглашения

GET /auth/invite/{token}

Находит приглашение, чтобы экран принятия мог показать, кому оно предназначено. Истёкшее приглашение всё равно возвращает 200, с valid: false, expired: true и только адресом электронной почты. Неизвестный токен возвращает 404. Публичный: токен — единственные учётные данные.

Параметры

Имя Тип Обязательный Описание
token string Да Токен приглашения из ссылки-приглашения в письме.

Ответ

{"data": {"valid": true, "expired": false, "email": "jane@example.com", "fullname": "Jane Doe"}}

Коды ответов

Код Описание
200 Состояние приглашения возвращено (включая истёкшие приглашения).
404 Это приглашение недействительно.

Принятие приглашения

POST /auth/invite/{token}

Создаёт приглашённую учётную запись и выполняет вход в неё. Адрес электронной почты, доступ и группы берутся из приглашения, и запрос не может их изменить. Пароль должен соответствовать политике паролей сайта (см. GET /auth/password-policy). Приглашение расходуется после создания учётной записи; истёкшее удаляется, и возвращается 410. Затем вход выполняет ту же проверку, что и POST /auth/token: если доступ из приглашения не даёт входа в API или админку (api.access, admin.login или суперпользователь), учётная запись всё равно создаётся, но токены не выдаются, а ответ — 403. При успехе ответ — пара токенов с объектом user и заголовком X-Invalidates: users:list. Вызывает onApiUserCreated и onApiInvitationAccepted. Публичный: токен — единственные учётные данные.

Параметры

Имя Тип Обязательный Описание
token string Да Токен приглашения из ссылки-приглашения в письме (параметр пути).
username string Да Имя пользователя (3–64 символа). Не может начинаться с точки или содержать .., а также не может содержать \ / ? * : ; { } или перевод строки.
password string Да Пароль. Должен соответствовать system.pwd_regex либо содержать не менее 8 символов, когда регулярное выражение не задано.
fullname string Нет Отображаемое имя (по умолчанию — имя из приглашения).
title string Нет Должность пользователя.

Запрос

{"username": "jane", "password": "Pa$$w0rd!", "fullname": "Jane Doe"}

Ответ

{"data": {"access_token": "eyJ...", "refresh_token": "eyJ...", "token_type": "Bearer", "expires_in": 3600, "user": {"username": "jane", "fullname": "Jane Doe", "email": "jane@example.com", "avatar_url": null, "super_admin": false, "access": {"api": {"access": true, "pages": {"read": true}}}, "content_editor": "", "demo_mode": {"enabled": false, "writable": [], "reset_interval": 30, "seconds_until_reset": null}}}}

Коды ответов

Код Описание
200 Учётная запись создана, вход выполнен.
403 Учётная запись создана, но приглашение не даёт доступа к API или входу в админку, поэтому токены не выданы.
404 Это приглашение недействительно.
409 Учётная запись с таким именем пользователя уже существует.
410 Срок действия этого приглашения истёк.
422 Отсутствуют поля, неверный формат имени пользователя или пароль не соответствует политике.

Конфигурация капчи

GET /auth/captcha

Сообщает, какая капча (если есть) защищает публичные эндпоинты входа, восстановления пароля и настройки, чтобы клиент мог отрисовать нужную проверку до отправки. flows указывает, какие из этих процессов защищены, а token_field называет поле тела, в которое помещается решённый токен (captcha_token). Для встроенного провайдера cap endpoint — базовый URL пары «запрос/погашение»; для turnstile и recaptcha (предоставляемых плагином Form) site_key — публичный ключ виджета, а reCAPTCHA также сообщает version. Секреты никогда не возвращаются. Публичный (аутентификация не требуется).

Ответ

{"data": {"enabled": true, "provider": "cap", "mode": "invisible", "token_field": "captcha_token", "flows": {"login": true, "forgot_password": true, "setup": false}, "endpoint": "https://example.com/api/v1/auth/captcha/"}}

Коды ответов

Код Описание
200 Конфигурация капчи возвращена. Когда капча выключена, enabled равно false, а provider — null.

Запрос капчи

POST /auth/captcha/challenge

Выдаёт клиенту задачу proof-of-work cap.js для решения. Доступно, только пока капча включена и активным провайдером является cap; иначе 404. Ответ — это формат передачи cap.js на верхнем уровне, а не обёртка data этого API, и он отправляется с Cache-Control: no-store. Публичный (аутентификация не требуется).

Ответ

{"challenge": {"c": 30, "s": 32, "d": 4}, "token": "72d323130ee3541275ca2dc1aa9607b4ca61095a08", "expires": 1787332679923}

Коды ответов

Код Описание
200 Задача выдана.
404 Задачи капчи недоступны (капча выключена или провайдер не cap).

Погашение капчи

POST /auth/captcha/redeem

Обменивает решённые подзадачи на одноразовый токен, который нужно отправить как captcha_token с запросом входа, восстановления пароля или настройки. Доступно, только пока капча включена и активным провайдером является cap; иначе 404. Ответ — это формат передачи cap.js на верхнем уровне, а не обёртка data этого API; success равно false, когда решения не проходят проверку. Публичный (аутентификация не требуется).

Параметры

Имя Тип Обязательный Описание
token string Да Токен задачи из POST /auth/captcha/challenge.
solutions array Да По одному целочисленному nonce на каждую подзадачу, по порядку.

Запрос

{"token": "72d323130ee3541275ca2dc1aa9607b4ca61095a08", "solutions": [1043, 88, 5121]}

Ответ

{"success": true, "token": "e734e7c49c34bb0d:d43a6be90ca08cf9f91171a5320e0a", "expires": 1787333298530}

Коды ответов

Код Описание
200 Результат погашения (проверьте success).
404 Задачи капчи недоступны (капча выключена или провайдер не cap).
422 Отсутствует token или solutions не является массивом.

Провайдеры SSO

GET /auth/sso/providers

Возвращает кнопки единого входа для экрана входа, собранные от каждого плагина, который отвечает на событие onApiLoginProviders (например, Login OAuth2). Пустой список означает вход только по паролю. Публичный (аутентификация не требуется).

Ответ

{"data": {"providers": [{"id": "github", "label": "GitHub", "icon": "fa-github", "plugin": "login-oauth2"}]}}

Коды ответов

Код Описание
200 Провайдеры возвращены (возможно, пустым списком).

Начало входа через SSO

GET /auth/sso/{provider}/start

Это переход браузера, а не XHR-вызов. Сохраняет целевой адрес возврата админки в сессии PHP, затем перенаправляет на URL авторизации провайдера, построенный плагином, который отвечает на onApiLoginStart (этот плагин хранит собственное состояние CSRF в той же сессии). Когда ни один плагин не обрабатывает провайдера, вместо этого перенаправляет обратно на /login?sso_error=<code> админки (по умолчанию sso_unavailable). Этот маршрут сохраняет cookie сессии, чтобы обратный вызов мог прочитать состояние. Публичный (аутентификация не требуется).

Параметры

Имя Тип Обязательный Описание
provider string Да Id провайдера из GET /auth/sso/providers (параметр пути).
returnTo string Нет Внутренний путь приложения, на который нужно попасть после входа (параметр запроса). Сохраняется только путь от корня; абсолютные URL, //host и управляющие символы отбрасываются.

Коды ответов

Код Описание
302 Перенаправление к провайдеру или на экран входа админки с параметром запроса sso_error.

Обратный вызов SSO

GET /auth/sso/{provider}/callback

Провайдер перенаправляет браузер сюда. Плагин, который отвечает на onApiLoginCallback, проверяет ответ и определяет пользователя Grav; затем выполняются те же проверки доступа к API, состояния учётной записи и 2FA, что и в POST /auth/token. Полученная пара токенов или запрос 2FA сохраняется под одноразовым кодом (действует 120 секунд), а браузер перенаправляется на <admin>/oauth-callback?code=<code> (плюс &returnTo=<path>, когда он был задан), где админка обменивает его через POST /auth/sso/exchange. При ошибке браузер переходит на <admin>/login?sso_error=<code> с sso_failed, sso_forbidden (нет доступа к API или учётная запись отключена) или кодом, специфичным для провайдера. Публичный (аутентификация не требуется).

Параметры

Имя Тип Обязательный Описание
provider string Да Id провайдера (параметр пути).

Коды ответов

Код Описание
302 Перенаправление обратно в админку с одноразовым кодом обмена или sso_error.

Обмен кода SSO

POST /auth/sso/exchange

Обменивает одноразовый код из перенаправления обратного вызова SSO на сохранённый результат входа. Тело ответа такое же, как возвращает POST /auth/token: либо пара токенов с объектом user, либо запрос requires_2fa, который нужно завершить через POST /auth/2fa/verify. Код удаляется при первом использовании и истекает через 120 секунд после обратного вызова. Публичный (аутентификация не требуется).

Параметры

Имя Тип Обязательный Описание
code string Да Шестнадцатеричный код из перенаправления oauth-callback.

Запрос

{"code": "9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08"}

Ответ

{"data": {"access_token": "eyJ...", "refresh_token": "eyJ...", "token_type": "Bearer", "expires_in": 3600, "user": {"username": "jane", "fullname": "Jane Doe", "email": "jane@example.com", "avatar_url": null, "super_admin": false, "access": {"api": {"access": true}}, "content_editor": "", "demo_mode": {"enabled": false, "writable": [], "reset_interval": 30, "seconds_until_reset": null}}}}

Коды ответов

Код Описание
200 Результат входа: пара токенов или запрос 2FA.
401 Недействительный или истёкший код обмена (неизвестный, искажённый, уже использованный или истёкший).
422 Отсутствует поле code.