Admin Authentication Endpoints¶
Аудитория: разработчики, backend инженеры, разработчики админских панелей Последнее обновление: 2025-11-17 Краткое содержание: Детальная документация Admin authentication endpoints — email/password login, JWT management, session verification. Полное руководство по интеграции для админских панелей.
Обзор Endpoints¶
| Метод | Endpoint | Описание | Auth Required |
|---|---|---|---|
| POST | /api/admin/auth/login |
Вход админа с credentials | ❌ Нет |
| POST | /api/admin/auth/refresh |
Обновление admin JWT токена | ✅ Да |
| GET | /api/admin/auth/verify |
Проверка admin сессии | ✅ Да |
| POST | /api/admin/auth/logout |
Выход из admin сессии | ✅ Да |
POST /api/admin/auth/login¶
Вход админа с email/password credentials.
Запрос¶
POST /api/admin/auth/login
Content-Type: application/json
{
"email": "admin@saga-test.com",
"password": "secure-admin-password"
}
Схема тела запроса:
| Поле | Тип | Обязательно | Описание |
|---|---|---|---|
email |
string | ✅ Да | Email адрес админа |
password |
string | ✅ Да | Пароль админа (bcrypt хеш на сервере) |
Правила валидации:
- Email должен быть валидного формата
- Password должен быть непустым
- Аккаунт должен иметь admin роль
Ответ¶
Успех (200 OK):
{
"success": true,
"data": {
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJhZG1pbl80NTZkZWYiLCJlbWFpbCI6ImFkbWluQHNhZ2EtdGVzdC5jb20iLCJyb2xlcyI6WyJhZG1pbiJdLCJwZXJtaXNzaW9ucyI6WyIqIl0sImlhdCI6MTY5NjM0ODgwMCwiZXhwIjoxNjk2NDM1MjAwLCJpc3MiOiJzYWdhLXBsYXRmb3JtIiwidHlwZSI6ImFkbWluIn0.signature",
"expiresIn": 86400,
"admin": {
"id": "admin_456def",
"email": "admin@saga-test.com",
"name": "Admin User",
"roles": ["admin"],
"permissions": ["*"],
"createdAt": "2025-07-01T10:00:00Z",
"lastLoginAt": "2025-10-03T12:34:56Z"
}
},
"timestamp": "2025-10-03T12:34:56Z"
}
Поля ответа:
| Поле | Тип | Описание |
|---|---|---|
data.token |
string | Admin JWT токен (действителен 24 часа) |
data.expiresIn |
number | Время истечения токена в секундах (86400 = 24 часа) |
data.admin.id |
string | ID админа |
data.admin.roles |
array | Роли админа ([\"admin\"], [\"operator\"], etc.) |
data.admin.permissions |
array | Разрешения админа (\"*\" = все разрешения) |
data.admin.lastLoginAt |
string | Timestamp предыдущего успешного входа |
Admin JWT Claims:
{
"sub": "admin_456def",
"email": "admin@saga-test.com",
"roles": ["admin"],
"permissions": ["*"],
"iat": 1696348800,
"exp": 1696435200,
"iss": "saga-platform",
"type": "admin"
}
Ошибки:
| Код статуса | Код ошибки | Описание |
|---|---|---|
| 400 | INVALID_EMAIL |
Невалидный формат email |
| 401 | INVALID_CREDENTIALS |
Email или password неверны |
| 403 | ACCOUNT_DISABLED |
Аккаунт админа заблокирован |
| 403 | INSUFFICIENT_PERMISSIONS |
Аккаунт не имеет admin роли |
| 429 | TOO_MANY_ATTEMPTS |
Превышен лимит попыток (5 попыток/15мин) |
Пример cURL¶
curl -X POST https://app.saga.surf/api/admin/auth/login \
-H "Content-Type: application/json" \
-d '{
"email": "admin@saga-test.com",
"password": "secure-admin-password"
}'
Пример TypeScript¶
const adminLogin = async (email: string, password: string) => {
const response = await fetch('/api/admin/auth/login', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({ email, password })
});
if (!response.ok) {
const error = await response.json();
throw new Error(error.error.message);
}
const { data } = await response.json();
// Сохранить admin токен (рекомендуется httpOnly cookie)
localStorage.setItem('saga_admin_token', data.token);
console.log('Admin logged in:', data.admin.email);
console.log('Roles:', data.admin.roles);
console.log('Permissions:', data.admin.permissions);
return data;
};
// Использование
await adminLogin('admin@saga-test.com', 'secure-password');
POST /api/admin/auth/refresh¶
Обновление admin JWT токена перед истечением (опциональная функция - Phase 2).
Запрос¶
POST /api/admin/auth/refresh
Authorization: Bearer eyJhbGciOiJIUzI1NiIs...
Content-Type: application/json
{
"refreshToken": "rt_abc123..."
}
Заголовки:
| Заголовок | Значение | Обязательно | Описание |
|---|---|---|---|
Authorization |
Bearer <token> |
✅ Да | Истекающий admin JWT токен |
Content-Type |
application/json |
✅ Да | Формат тела запроса |
Схема тела запроса:
| Поле | Тип | Обязательно | Описание |
|---|---|---|---|
refreshToken |
string | ✅ Да | Refresh токен (выдается при login) |
Примечание: Функция refresh токенов в Phase 2. Phase 1 требует повторного входа после 24 часов.
Ответ¶
Успех (200 OK):
{
"success": true,
"data": {
"token": "eyJhbGciOiJIUzI1NiIs...",
"expiresIn": 86400,
"refreshToken": "rt_def456..."
},
"timestamp": "2025-10-03T12:34:56Z"
}
Ошибки:
| Код статуса | Код ошибки | Описание |
|---|---|---|
| 401 | TOKEN_EXPIRED |
Текущий JWT токен истёк |
| 401 | INVALID_REFRESH_TOKEN |
Refresh токен невалиден или истёк |
| 401 | REFRESH_TOKEN_REVOKED |
Refresh токен отозван (security) |
Пример cURL¶
ADMIN_TOKEN="eyJhbGciOiJIUzI1NiIs..."
REFRESH_TOKEN="rt_abc123..."
curl -X POST https://app.saga.surf/api/admin/auth/refresh \
-H "Authorization: Bearer $ADMIN_TOKEN" \
-H "Content-Type: application/json" \
-d "{\"refreshToken\": \"$REFRESH_TOKEN\"}"
Пример TypeScript¶
const refreshAdminToken = async () => {
const currentToken = localStorage.getItem('saga_admin_token');
const refreshToken = localStorage.getItem('saga_admin_refresh_token');
const response = await fetch('/api/admin/auth/refresh', {
method: 'POST',
headers: {
'Authorization': `Bearer ${currentToken}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({ refreshToken })
});
const { data } = await response.json();
// Обновить сохранённые токены
localStorage.setItem('saga_admin_token', data.token);
localStorage.setItem('saga_admin_refresh_token', data.refreshToken);
console.log('Admin token refreshed successfully');
return data.token;
};
GET /api/admin/auth/verify¶
Проверка валидности admin JWT токена и статуса сессии.
Запрос¶
Заголовки:
| Заголовок | Значение | Обязательно | Описание |
|---|---|---|---|
Authorization |
Bearer <token> |
✅ Да | Admin JWT токен |
Ответ¶
Успех (200 OK):
{
"success": true,
"data": {
"valid": true,
"admin": {
"id": "admin_456def",
"email": "admin@saga-test.com",
"name": "Admin User",
"roles": ["admin"],
"permissions": ["*"]
},
"expiresAt": "2025-10-04T12:34:56Z",
"issuedAt": "2025-10-03T12:34:56Z"
},
"timestamp": "2025-10-03T14:00:00Z"
}
Поля ответа:
| Поле | Тип | Описание |
|---|---|---|
data.valid |
boolean | true если токен валиден, false иначе |
data.admin |
object | Информация об админе из JWT claims |
data.expiresAt |
string | Timestamp истечения токена |
data.issuedAt |
string | Timestamp создания токена |
Ошибки:
| Код статуса | Код ошибки | Описание |
|---|---|---|
| 401 | TOKEN_MISSING |
Отсутствует Authorization заголовок |
| 401 | TOKEN_EXPIRED |
JWT токен истёк |
| 401 | TOKEN_INVALID |
Невалидная подпись JWT или malformed |
| 403 | NOT_ADMIN_TOKEN |
Тип токена ≠ \"admin\" (предоставлен user токен) |
Пример cURL¶
ADMIN_TOKEN="eyJhbGciOiJIUzI1NiIs..."
curl -X GET https://app.saga.surf/api/admin/auth/verify \
-H "Authorization: Bearer $ADMIN_TOKEN"
Пример TypeScript¶
const verifyAdminSession = async () => {
const token = localStorage.getItem('saga_admin_token');
const response = await fetch('/api/admin/auth/verify', {
headers: {
'Authorization': `Bearer ${token}`
}
});
const { data } = await response.json();
if (!data.valid) {
// Токен невалиден, редирект на login
console.log('Admin session invalid, redirecting to login');
window.location.href = '/admin/login';
return false;
}
console.log('Admin session valid');
console.log('Expires at:', data.expiresAt);
console.log('Roles:', data.admin.roles);
return data;
};
// Проверка сессии при инициализации приложения
await verifyAdminSession();
🚪 POST /api/admin/auth/logout¶
Выход из admin сессии и инвалидация токена.
Запрос¶
Заголовки:
| Заголовок | Значение | Обязательно | Описание |
|---|---|---|---|
Authorization |
Bearer <token> |
✅ Да | Admin JWT токен |
Ответ¶
Успех (200 OK):
{
"success": true,
"data": {
"message": "Admin logged out successfully",
"loggedOutAt": "2025-10-03T14:30:00Z"
},
"timestamp": "2025-10-03T14:30:00Z"
}
Ошибки:
| Код статуса | Код ошибки | Описание |
|---|---|---|
| 401 | TOKEN_MISSING |
Отсутствует Authorization заголовок |
| 401 | TOKEN_INVALID |
Невалидная подпись JWT |
Пример cURL¶
ADMIN_TOKEN="eyJhbGciOiJIUzI1NiIs..."
curl -X POST https://app.saga.surf/api/admin/auth/logout \
-H "Authorization: Bearer $ADMIN_TOKEN"
Пример TypeScript¶
const adminLogout = async () => {
const token = localStorage.getItem('saga_admin_token');
await fetch('/api/admin/auth/logout', {
method: 'POST',
headers: {
'Authorization': `Bearer ${token}`
}
});
// Очистить сохранённые токены
localStorage.removeItem('saga_admin_token');
localStorage.removeItem('saga_admin_refresh_token');
console.log('Admin logged out successfully');
// Редирект на login
window.location.href = '/admin/login';
};
Лучшие практики безопасности¶
Для админских разработчиков¶
✅ ДЕЛАЙТЕ:
- Храните admin JWT в httpOnly cookies (защита от XSS)
- Используйте только HTTPS для admin endpoints
- Реализуйте auto-logout при истечении токена
- Логируйте все события админской аутентификации
- Используйте строгие требования к паролям (12+ символов, сложность)
- Реализуйте 2FA для admin аккаунтов (Phase 2)
- Rate limit попыток входа (5 попыток/15мин)
- Мониторьте неудачные попытки входа
❌ НЕ ДЕЛАЙТЕ:
- Не храните admin JWT в localStorage (высокоценная цель)
- Не делитесь admin credentials
- Не используйте одинаковый JWT secret для user и admin токенов
- Не игнорируйте подозрительные паттерны входа
- Не разрешайте слабые админские пароли
- Не пропускайте audit логирование
Система разрешений админа¶
Уровни разрешений:
| Роль | Разрешения | Описание |
|---|---|---|
admin |
[\"*\"] |
Полный доступ к системе |
operator |
[\"investments:read\", \"investments:approve\", \"withdrawals:read\", \"withdrawals:approve\"] |
Операции с инвестициями/выводами |
support |
[\"users:read\", \"investments:read\", \"transactions:read\"] |
Доступ только для чтения |
readonly |
[\"dashboard:read\", \"reports:read\"] |
Только просмотр панели управления |
Проверки разрешений:
// Пример backend middleware
function requirePermission(permission: string) {
return (req, res, next) => {
const adminClaims = req.admin; // Из JWT
if (adminClaims.permissions.includes('*')) {
return next(); // Admin роль = все разрешения
}
if (!adminClaims.permissions.includes(permission)) {
return res.status(403).json({
success: false,
error: {
code: 'PERMISSION_DENIED',
message: `Permission required: ${permission}`
}
});
}
next();
};
}
// Использование
router.put('/api/admin/investments/:id/approve',
requirePermission('investments:approve'),
approveInvestment
);
Управление Admin сессиями¶
Обработка таймаута сессии¶
// Авто-обновление токена перед истечением
const setupTokenRefresh = (expiresIn: number) => {
// Обновить токен за 5 минут до истечения
const refreshTime = (expiresIn - 300) * 1000;
setTimeout(async () => {
try {
await refreshAdminToken();
console.log('Admin token refreshed automatically');
} catch (error) {
console.error('Token refresh failed, redirecting to login');
window.location.href = '/admin/login';
}
}, refreshTime);
};
// При входе
const { token, expiresIn } = await adminLogin(email, password);
setupTokenRefresh(expiresIn);
Отслеживание активности¶
// Отслеживание активности админа
const trackAdminActivity = async (action: string, metadata?: any) => {
await fetch('/api/admin/activity/log', {
method: 'POST',
headers: {
'Authorization': `Bearer ${adminToken}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({
action,
metadata,
timestamp: new Date().toISOString()
})
});
};
// Использование
await trackAdminActivity('investment_approved', { investmentId: 'inv_123' });
await trackAdminActivity('user_suspended', { userId: 'user_456' });
Связанная документация¶
Deep Dives:
- Authentication Guide - Общие концепции аутентификации
- Error Handling - Справочник кодов ошибок
Другие Admin Endpoints:
- User Management - Операции управления пользователями
- Investment Management - Операции управления инвестициями
- Dashboard - Endpoints панели управления
Безопасность:
📋 Метаданные¶
Версия: 2.6.268
Обновлено: 2025-10-21
Статус: Published