InfraGuard

Вход и аутентификация

Как работает сеансовый вход в консоль, как сеанс пересинхронизируется при каждом запросе и как аутентифицируется внешний API приёма данных.

Обзор — что делает этот механизм

В InfraGuard есть две плоскости аутентификации:

  1. Веб-консоль = сеансовый вход. Оператор входит по login_id + password, и AuthController создаёт собственный сеанс. Дальше каждая страница консоли проходит через посредник infr.auth (InfrAuth), который проверяет сеанс и при каждом запросе заново считывает из базы данных уровень, имя и язык пользователя, чтобы копия в сеансе оставалась актуальной.
  2. Внешний API приёма данных = аутентификация по API-ключу без состояния. Когда внешнее приложение отправляет инциденты, отчёты о резервном копировании или результаты сканирования безопасности, оно аутентифицируется токеном API-ключа (Authorization: Bearer … или X-Infr-Api-Key) через посредник infr.apikey, а не через сеанс. Ни сеанса, ни CSRF.

Ключевые особенности:

Когда это применять

Устройство экрана

Экран входа (/login) — это одна простая карточка.

Элемент Описание
Бренд · слоган Логотип Infra**Guard** + «Консоль эксплуатации, защиты и отказоустойчивости конвергентной инфраструктуры»
Логин Поле login_id. autocomplete=username, фокус ставится автоматически
Пароль Поле password + значок глаза для показа и скрытия
Баннер ошибки При неудаче: «Указанные данные не совпадают с нашими записями.»
Скрытое поле next Путь возврата после входа (должен начинаться с /)
Кнопка отправки «Войти →»

Форма входа несёт стандартный токен Blade @csrf. Консоль защищена сеансом + CSRF и не запрашивает в интерфейсе отдельный bearer-токен.

Как пользоваться

Вход в систему

  1. Откройте /login (если вы уже вошли, вас перенаправит на /).
  2. Введите свои Login ID и Password.
    • Проверка: login_id — не более 60 символов, password — от 4 до 120 символов.
  3. Нажмите Войти. Сервер ищет учётную запись в infr_user по login_id + is_close=0 и проверяет пароль.
  4. При успехе сеанс пересоздаётся (session()->regenerate()), и вас отправляют на next (или на /).

Успешный вход заполняет следующие ключи сеанса:

Ключ сеанса Значение
infr_user_id infr_user.id (источник истины для «аутентифицирован»)
infr_login_id Логин
infr_user_level user_level (целое) — Уровень RBAC
infr_name Отображаемое имя
infr_lang Язык интерфейса (по умолчанию ko)

Также в столбец last_log записывается текущее время.

Выход из системы

Время жизни сеанса и пересинхронизация при каждом запросе

Каждая страница консоли проходит через infr.auth (InfrAuth), который при каждом запросе:

  1. Заново загружает пользователя по infr_user_id из сеанса (горячий путь, минимум столбцов: id · login_id · name · email · user_level · role_id · team_id · lang · avatar · is_close).
  2. Если учётной записи нет или у неё is_close=1 (отключена), уничтожает сеанс и перенаправляет на /login (либо возвращает JSON 401).
  3. Перезаписывает infr_user_level · infr_name · infr_lang значениями из базы данных — поэтому изменённые администратором уровень, имя или язык применяются со следующего запроса без повторного входа.
  4. Кладёт модель пользователя в атрибут запроса infr_user и задаёт язык интерфейса через app()->setLocale().
  5. Вызывает OpsPolicy::markPresence(), чтобы отметить присутствие (экономный режим операционной политики использует это, чтобы решить, «работает ли сейчас кто-то в консоли», и регулировать сбор данных из базы — см. Операционная политика).

Время жизни сеанса определяется параметром SESSION_LIFETIME (по умолчанию 120 минут).

У входа в консоль нет отдельного флажка «запомнить меня». Сеанс держится указанное выше время; после его истечения нужно войти заново.

Аутентификация внешнего API приёма данных (bearer-ключ)

Когда внешнее приложение обращается к /api/v1/*, оно аутентифицируется API-ключом (без состояния — ни сеанса, ни CSRF).

Способ Пример заголовка
Bearer Authorization: Bearer YOUR_KEY
Собственный заголовок X-Infr-Api-Key: YOUR_KEY

Как это работает:

Основные конечные точки:

# Проверка связи / ключа
curl -sS https://infraguard.example.com/api/v1/ping \
  -H "Authorization: Bearer YOUR_KEY"

# Автоматическая регистрация инцидента (с дедупликацией · source=pulse)
curl -sS -X POST https://infraguard.example.com/api/v1/incidents \
  -H "Authorization: Bearer YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{"title":"NPE in checkout","fingerprint":"abc123","severity":"crit"}'

Выпускайте и отзывайте ключи, а также копируйте код интеграции в разделе Администрирование ▸ API-ключи (ключ в открытом виде показывается только один раз, при выпуске).

Step-up — защита разрушительных действий

Рискованные действия — блокировка, разблокировка, восстановление или изменение настроек — защищены не повторным вводом пароля, а тремя рубежами:

  1. Повторная проверка уровня — действия записи требуют как минимум уровня записи (2 и выше), а административные действия — уровня администратора (10), и это перепроверяется на сервере.
  2. Журнал аудита — значения до и после, а также исполнитель и IP записываются в журнал аудита (infr_audit_log).
  3. Подтверждение в интерфейсе — перед действием в интерфейсе появляется диалог подтверждения (step-up).

Источники данных

Объект Назначение
infr_user Учётные записи операторов. Столбцы: login_id · password · user_level · name · email · lang · is_close · role_id · team_id · last_log · avatar
Хранилище сеансов (Redis) Ключи сеанса, например infr_user_id (REDIS_PREFIX infr_)
infr_api_key Хеш (key_hash) ключей API приёма данных · is_active · use_count · last_used_at/ip
infr_audit_log Аудиторский след разрушительных действий и действий с безопасностью

Столбец infr_user.password никогда не попадает в журналы, URL или cookie. Открытое значение API-ключа показывается только при выпуске; в базе данных остаётся лишь хеш.

Права доступа

Барьеры на уровне URL (проверяются после входа):

Область Посредник Минимальный уровень
Обычная консоль (Обзор · Инфраструктура · чтение Активов) infr.auth Только вход (1)
/security · /backup infr.level:2 2
/admin infr.level:10 10
/horizon · /pulse infr.admin 10
Раздел разработки infr.dev 9

Ступени уровней: demo=1 · staff=5 · admin=10. Полную политику см. в разделе Уровни доступа.

Устранение неполадок и частые вопросы

Я вхожу, но меня снова и снова возвращает на /login. Cookie сеанса не сохраняется (несовпадение домена или SESSION_DOMAIN, либо cookie только для HTTPS отдаётся по HTTP), или учётной записи выставлено is_close=1 (отключена). Попросите администратора проверить состояние учётной записи.

Я вижу «Указанные данные не совпадают с нашими записями.» Опечатка в login_id, неверный пароль или отключённая учётная запись (is_close=1). Из соображений безопасности сообщение не уточняет, что именно.

Учётная запись не может войти. Пароль может быть неверным или учётная запись отключена. Администратор сбрасывает пароль в разделе Пользователи и команды.

Я вхожу, но не могу открыть /admin. Ваш уровень ниже 10. Раздел /admin защищён посредником infr.level:10, поэтому туда попадают только администраторы. Аналогично /security и /backup требуют уровня 2 и выше.

AJAX-запрос возвращает 401. Сеанс консоли истёк. Обновите страницу и войдите заново. JSON-запросы получают {"error":"unauthenticated"} с кодом 401 вместо перенаправления.

Администратор повысил мой уровень, но это не применилось. InfrAuth пересинхронизирует сеанс при каждом запросе, поэтому изменение применяется со следующего перехода — повторный вход не нужен. Обновите страницу, чтобы применить сразу.

Меню или интерфейс отображаются на неожиданном языке. Язык интерфейса определяется полем infr_user.lang (ключ сеанса infr_lang) и пересинхронизируется при каждом запросе. Измените его в разделе Локализация.

API возвращает 401 invalid_api_key / 429 rate_limited. Неактивный или неверно введённый ключ даёт 401; более 120 запросов в минуту дают 429 (+ Retry-After). Проверьте состояние ключа в разделе API-ключи и снизьте частоту обращений.

Смежные темы

로그인 화면
로그인 화면