Authentication
Finance OS API поддерживает два механизма аутентификации. Оба используют стандартный заголовок Authorization: Bearer ... — клиенту не нужно их различать, middleware на сервере определит формат сам.
Сравнение
| Name | Type | Required | Description |
|---|---|---|---|
API Keys
|
Stripe-style
|
optional | Для серверных интеграций: CI/CD, торговые боты, партнёрские системы, бэкенды собственных сервисов. Одна пара ключей на окружение (Live + Sandbox). Регенерируются вручную через ЛК. |
Mobile Sessions
|
Sanctum tokens
|
optional | Для пользовательских приложений, где конечный юзер сам вводит email+password. Каждый login создаёт отдельный токен-сессию. Отзывается через logout. |
Пишете мобильное/десктоп-приложение, где пользователь сам логинится → используйте Mobile Sessions.
API Keys (для серверов)
Похоже на то, как работают Stripe / Plaid / Twilio: у каждого пользователя две пары ключей — для Live (production) и Sandbox (test). Каждая пара состоит из публичного и секретного ключа.
Как сгенерировать
- Войти в fin-os.io
- Сайдбар → Настройки → API ключи
- Переключить тоггл MAIN / SANDBOX в нужное окружение
- Нажать «Сгенерировать Live ключи» (или Sandbox)
- В модальном окне скопировать
sk_live_…/sk_test_…— он показывается только один раз
Формат ключей
| Name | Type | Required | Description |
|---|---|---|---|
pk_live_xxx
|
~36 chars
|
optional | Public Key (Live). Зарезервирован под frontend-кейсы (v1.1). Сейчас не используется для аутентификации — можно безопасно отображать в UI или коммитить. |
sk_live_xxx
|
~48 chars
|
optional | Secret Key (Live). Это и есть ваш Bearer-токен. Хранится на сервере как hash — потерянный ключ восстановить нельзя, только перегенерировать. |
pk_test_xxx
|
~36 chars
|
optional | Public Key (Sandbox). Для тестового окружения. |
sk_test_xxx
|
~48 chars
|
optional | Secret Key (Sandbox). Используйте на dev/staging — реальные транзакции не создаются (sandbox-режим прокидывается v1.1). |
Использование
Authorization: Bearer sk_live_abc123...
Это всё. Передавайте на каждом запросе к защищённым endpoints. Никакого логина, никаких рефреш-токенов.
Lifecycle
- Срок жизни: ключ живёт до явной перегенерации. По таймеру не истекает.
- Регенерация: кнопка «Перегенерировать» в кабинете создаёт новую пару и инвалидирует старую немедленно. Все клиенты со старым ключом получат 401, пока не обновят.
- Отзыв без выпуска нового: отдельной операции нет — перегенерируйте, чтобы убить старый ключ. Если нужно временно «выключить» интеграцию — отзовите доступ на стороне клиента.
- Last-used трекинг: на странице ключей видно
last_used_atиlast_used_ip— полезно для аудита.
sk_live_… попал в git, чат, лог — немедленно жмите «Перегенерировать» в кабинете. Через несколько секунд старый ключ перестанет работать.
Mobile Sessions (для приложений)
Под капотом — Laravel Sanctum. Каждый login через POST /api/mobile/login создаёт новую запись в personal_access_tokens и возвращает токен-сессию клиенту.
Flow
POST /api/mobile/login
Content-Type: application/json
{
"email": "you@example.com",
"password": "...",
"device_name": "iPhone 15"
}
# → 200 OK
{
"data": {
"token": "123|aBcDeFgHiJkLmNoPqRsTuVwXyZ1234567890aBcDeFgH",
...
}
}
Login параметры
| Name | Type | Required | Description |
|---|---|---|---|
email
|
string
|
required | Email пользователя. |
password
|
string
|
required | Пароль. |
two_factor_code
|
string
|
optional |
6-значный TOTP-код. Передавайте, если первый запрос вернул requires_2fa: true.
|
recovery_code
|
string
|
optional | Одноразовый recovery-код (10 символов). Альтернатива TOTP при утере телефона. |
device_name
|
string
|
optional |
Имя устройства — отображается в /api/mobile/sessions.
|
remember
|
boolean
|
optional |
Если true — токен живёт 365 дней. Иначе 30 дней.
Default:
false |
Формат токена
Возвращается строкой вида 123|aBcDeFgH…:
123— ID записи вpersonal_access_tokens|— разделительaBcDeFgH…(40 символов) — собственно секрет
Передавайте всю строку целиком: Authorization: Bearer 123|aBcDeFgH...
Двухфакторная аутентификация
Если на аккаунте включён 2FA, первый POST /api/mobile/login вернёт 422 с телом:
{
"message": "Two-factor authentication required.",
"error_code": "TWO_FACTOR_REQUIRED",
"requires_2fa": true
}
Запросите код у пользователя и повторите login с добавленным two_factor_code (или recovery_code).
Управление сессиями
| Name | Type | Required | Description |
|---|---|---|---|
GET /api/mobile/user
|
|
optional | Профиль владельца текущего токена. |
GET /api/mobile/sessions
|
|
optional | Список всех активных Sanctum-сессий пользователя. |
POST /api/mobile/logout
|
|
optional | Отозвать текущий токен. Прочие сессии продолжают работать. |
DELETE /api/mobile/sessions/{id}
|
|
optional | Отозвать конкретную сессию (например, выйти с другого устройства). |
DELETE /api/mobile/sessions/all
|
|
optional | Отозвать все сессии кроме текущей. |
Как сервер различает форматы
Один и тот же endpoint принимает оба типа Bearer'а — для клиента это прозрачно:
# Вариант A: API key
Authorization: Bearer sk_live_aBcDeFgH...
# Вариант B: Sanctum session
Authorization: Bearer 123|aBcDeFgH...
Под капотом middleware-стек:
AuthenticateApiKeyсмотрит на bearer. Если совпадает с regex/^sk_(live|test)_[A-Za-z0-9]+$/— ищет вapi_keys.secret_hash, и при совпадении ставит пользователя в Sanctum-guard.auth:sanctumотрабатывает дальше. Если юзер уже выставлен предыдущим middleware — пропускает. Если нет — пытается резолвить bearer как Sanctum-токен (форматid|secret).
Поэтому никакой разницы в коде клиента — пишите любой формат, всё работает.
Scopes (v1.1)
В v1 у всех ключей — полный доступ к ресурсам владельца (abilities = ['*'] в Sanctum). В v1.1 планируется:
- API Keys scopes:
read-only,trading-only,withdrawal,business - Public key scope:
pk_live_…получит read-only-доступ к публичным эндпоинтам (тикеры, статус сети) — безопасно встраивать в frontend - Sandbox-режим: сейчас
sk_test_…работает как обычный ключ; в v1.1 sandbox начнёт реально подменять транзакции на mock'и
Ошибки
Best practices
- Не коммитьте
sk_live_…в git — храните в.env, AWS Secrets Manager, HashiCorp Vault. - Используйте
sk_test_…на dev/staging,sk_live_…только в production. - Для каждой среды/команды — отдельный пользовательский аккаунт с собственными ключами. Это упрощает revoke при увольнении.
- Mobile Sessions — не для серверов: они изнашиваются при logout/2FA-rotate, и из CI-пайплайна это будет постоянно ломаться.
- IP-биндинг (
session_ip_binding) можно включить на уровне пользователя в Настройках — тогда сессии при смене IP запросят повторный логин.