Аккаунты и SSO
.sso переносит API старого PHP .back на Node.js. Исходники нового сервиса не отключают PHP автоматически. Совместимость старого протокола, новый упрощённый вход и перевод клиентов являются отдельными этапами.
Вход браузера без ключей приложения
В свежей рабочей ветке SSO реализован отдельный cookie-auth router. Браузер не передаёт client ID, client key или client secret:
| Маршрут | Запрос/назначение |
|---|---|
POST /auth/login | JSON login/password; устанавливает HttpOnly cookie, возвращает account, access_token и csrf_token |
GET /auth/session | Cookie; восстановление account и короткого access token |
POST /auth/logout | Cookie и X-CSRF-Token; отзыв сессии и очистка cookie |
GET /auth/profile | Cookie; собственный профиль |
GET /auth/projects | Cookie; доступные проекты/серверы, v2 DTO проходит дополнительный security review |
POST /auth/network-token | Cookie, X-CSRF-Token, project_id/server_id; scoped personal token |
GET /auth/steam/start | mode=login или link; redirect к Steam, для link нужна сессия |
GET /auth/steam/callback | Только проверенный callback Steam; redirect на настроенный done URL |
Все POST требуют разрешённый Origin; logout/network-token дополнительно требуют session-bound CSRF token. Используйте credentials: include, восстанавливайте вход через /auth/session. HttpOnly cookie не читается JavaScript; access token хранится в памяти, пароль и session credentials не сохраняются в localStorage.
Вне явно включённого HTTP loopback-профиля cookie имеет имя __Host-ozsso и атрибуты Secure, HttpOnly, SameSite=Lax, Path=/. Loopback dev использует ozsso. Сессии и rate limits хранятся в общей БД. Logout прекращает обновление сессии, а уже выданный короткий access token имеет ограниченный срок; смена auth hash при восстановлении пароля отзывает его account version.
SSO выпускает RS256 personal token до пяти минут с issuer/audience, sub, scope account/panel, ver, iat, exp, jti; panel scope содержит pid/sid. Приём этих токенов в Network требует отдельного verifier и настройки доверенного public key. В Network коммит 50e0478 добавил verifier common/SsoAuth.js, HTTP Bearer и personal Socket.IO account/panel scope. Он проверяет доверенный локальный public PEM, алгоритм, issuer/audience/kid, срок, типы claims и свежую account version. Source и целевые fixtures существуют; полный браузерный сценарий и production acceptance проверяются отдельно.
Регистрация, восстановление и Steam
Keyless маршруты: POST /auth/register/send-code, /auth/register/confirm, /auth/register, /auth/restore/send-code, /auth/restore/confirm, /auth/restore/find, /auth/restore. Поля сверяйте в OpenAPI; key здесь является контактом/ключом подтверждения существующего бизнес-потока, а не секретом приложения браузера. Credentials registration-приложения подставляет сам SSO.
Steam login работает для уже привязанного аккаунта. Link требует текущую сессию и не сливает разные аккаунты. Исходники проверяют фиксированный провайдер, точный return_to/claimed_id, server-side check_authentication, одноразовый state и nonce с ограниченным временем. Это проверяемые защитные механизмы, а не гарантия отсутствия уязвимостей или доказательство входа через настоящий Steam-аккаунт в локальной фикстуре.
На зафиксированном срезе review нашёл незавершённые места: v2 projects DTO требует отдельного allowlist вместо удаления одного поля, а конкурентная Steam-привязка требует общего атомарного invariant. Исправления принадлежат SSO owner. Наличие маршрута и защитных проверок выше не означает завершённую security-приёмку.
Реализованная поверхность
Пользовательский поток включает вход, регистрацию, восстановление доступа, профиль и выбор доступного проекта. Разрешённые браузерные маршруты перечислены в SSO HTTP API; внутренние интеграции и legacy aliases не являются публичным API.
Текущий протокол
Маршруты принимают /methods/group.method, JSON/urlencoded/form-data. Query и body объединяются, body имеет приоритет. Ответы сохраняют PHP-форму:
{"status":"success","response":{}}{"status":"error","error_name":"token_invalid","error_msg":"..."}Это отличается от error: {name, message} Network. Не показывайте пользователю сырой unknown_error, если backend вернул переведённое имя/сообщение.
Совместимый /methods/front.Auth требует client_id, user_login, user_password, client_key. С api_v=2 application-поля передаются plain по HTTPS и ключ проверяется независимо от старого формата XXXX-XXXX. Без api_v сохраняется legacy ApiEncrypt. Оба режима остаются compatibility API для существующих приложений; новый браузерный вход использует /auth без ключей приложения.
Безопасность и перенос
Сервис проверяет доступ приложения, аккаунт, auth hash, блокировку/удаление пользователя и права метода. Совместимость crypto/имён проверяется отдельными PHP golden-тестами; HTTP/MySQL сценарии имеют собственные fixtures. Наличие тестов в репозитории не означает успешный перенос всей системы.
В исправлениях относительно PHP: приватные поля доступны только своему профилю, регистрация привязана к подтверждённому контакту, исчерпанные попытки кода не разрешают удаление, код восстановления расходуется. Секреты приложения находятся в окружении, а не в документации. Сторонний token ID без поддержанной таблицы отвергается.
При переключении клиентов проверьте login → профиль → Network token → подключение панели, logout, восстановление и истечение сессии. Центральные аккаунты и собственная проектная подписка Network не являются одной таблицей или одним токеном.
Источники: .sso/src/app.js, src/methods, src/legacy/validator.js, response.js, docs/legacy-route-coverage.md, README. Снимок версии исходников.
