Реалізація API Key аутентифікації для веб-застосунку

Наша компанія займається розробкою, підтримкою та обслуговуванням сайтів будь-якої складності. Від простих односторінкових сайтів до масштабних кластерних систем, побудованих на мікро сервісах. Досвід розробників підтверджено сертифікатами від вендорів.
Розробка та обслуговування будь-яких видів сайтів:
Інформаційні сайти або веб-програми
Сайти візитки, landing page, корпоративні сайти, онлайн каталоги, квіз, промо-сайти, блоги, ресурси новин, інформаційні портали, форуми, агрегатори
Сайти або веб-програми електронної комерції
Інтернет-магазини, B2B-портали, маркетплейси, онлайн-обмінники, кешбек-сайти, біржі, дропшиппінг-платформи, парсери товарів
Веб-програми для управління бізнес-процесами
CRM-системи, ERP-системи, корпоративні портали, системи управління виробництвом, парсери інформації
Сайти або веб-програми електронних послуг
Дошки оголошень, онлайн-школи, онлайн-кінотеатри, конструктори сайтів, портали надання електронних послуг, відеохостинги, тематичні портали

Це лише деякі з технічних типів сайтів, з якими ми працюємо, і кожен із них може мати свої специфічні особливості та функціональність, а також бути адаптованим під конкретні потреби та цілі клієнта.

Пропоновані послуги
Показано 1 з 1 послугУсі 2065 послуг
Реалізація API Key аутентифікації для веб-застосунку
Проста
від 1 робочого дня до 3 робочих днів
Часті питання
Наші компетенції:
Етапи розробки
Останні роботи
  • image_website-b2b-advance_0.png
    Розробка сайту компанії B2B ADVANCE
    1262
  • image_web-applications_feedme_466_0.webp
    Розробка веб-додатків для компанії FEEDME
    1171
  • image_websites_belfingroup_462_0.webp
    Розробка веб-сайту для компанії БЕЛФІНГРУП
    874
  • image_ecommerce_furnoro_435_0.webp
    Розробка інтернет магазину для компанії FURNORO
    1094
  • image_crm_enviok_479_0.webp
    Розробка веб-додатків для компанії Enviok
    831
  • image_bitrix-bitrix-24-1c_fixper_448_0.png
    Розробка веб-сайту для компанії ФІКСПЕР
    851

Аутентифікація за допомогою API-ключа для веб-додатків

API-ключі — найпростіший механізм аутентифікації для взаємодії машина-машина (server-to-server). Без OAuth-flow, без refresh-токенів, без сесій. Клієнт передає ключ у заголовку або параметрі запиту, сервер його перевіряє. Підходить для публічних API, інтеграцій з партнерами та інструментів CLI.

Генерування та зберігання ключів

Ключ повинен бути досить випадковим — мінімум 32 байти:

// Генерування ключа
$key = 'sk_' . bin2hex(random_bytes(32)); // sk_ + 64 hex = 67 символів
// Приклад: sk_a3f9b12e8c4d7e1f0a2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d7e8f9a0b1c2d3e4f5

// Ніколи не зберігаємо ключ у відкритому вигляді — тільки хеш
$hash = hash('sha256', $key);

DB::table('api_keys')->insert([
    'user_id'    => $userId,
    'name'       => $request->name,
    'key_prefix' => substr($key, 0, 8), // для відображення користувачу
    'key_hash'   => $hash,
    'scopes'     => json_encode(['read:articles', 'write:articles']),
    'last_used_at' => null,
    'expires_at' => now()->addYear(),
]);

// Ключ показуємо користувачу ОДИН РАЗ — при створенні
return response()->json(['key' => $key], 201);

Зберігаємо тільки хеш — при витоку бази ключі непридатні.

Перевірка ключа

// Middleware ApiKeyAuth
public function handle(Request $request, Closure $next): Response
{
    $key = $request->bearerToken()  // Authorization: Bearer sk_...
        ?? $request->header('X-Api-Key') // X-Api-Key: sk_...
        ?? $request->query('api_key');   // ?api_key=sk_... (уникати у URL)

    if (!$key) {
        return response()->json(['error' => 'API key required'], 401);
    }

    $hash = hash('sha256', $key);
    $apiKey = ApiKey::where('key_hash', $hash)
        ->where(fn($q) => $q->whereNull('expires_at')->orWhere('expires_at', '>', now()))
        ->first();

    if (!$apiKey) {
        return response()->json(['error' => 'Invalid or expired API key'], 401);
    }

    // Оновлюємо last_used_at асинхронно, щоб не сповільнювати запит
    dispatch(fn() => $apiKey->update(['last_used_at' => now()]))->afterResponse();

    $request->setUserResolver(fn() => $apiKey->user);
    $request->attributes->set('api_key', $apiKey);

    return $next($request);
}

Scopes (дозволи)

Ключ повинен мати мінімально необхідні права:

// Перевірка scope у контролері або Middleware
public function store(Request $request): JsonResponse
{
    $apiKey = $request->attributes->get('api_key');

    if (!in_array('write:articles', $apiKey->scopes ?? [])) {
        return response()->json(['error' => 'Insufficient scope'], 403);
    }

    // ...
}

Список scopes визначається під час створення ключа користувачем (або призначається фіксований набір).

Безпека

Передача ключа:

  • Тільки через HTTPS
  • Переважно у заголовку Authorization: Bearer або X-Api-Key
  • Не у URL (потрапляє у логи, історію браузера, referer)

Ротація ключів:

// Інвалідуємо старий ключ при створенні нового
ApiKey::where('user_id', $userId)->where('name', $name)->delete();

Аудит використання:

ApiKeyUsageLog::create([
    'api_key_id' => $apiKey->id,
    'ip'         => $request->ip(),
    'endpoint'   => $request->path(),
    'method'     => $request->method(),
    'status'     => null, // заповнюється у Terminate middleware
]);

Обмеження частоти за ключем:

RateLimiter::for('api-key', function (Request $request) {
    $apiKey = $request->attributes->get('api_key');
    return Limit::perMinute($apiKey->rate_limit ?? 60)->by($apiKey->id);
});

UX у панелі керування

Список ключів з відображенням key_prefix (перші 8 символів):

sk_a3f9b1...  "Production integration"    Останнє використання: 2 години тому   [Видалити]
sk_c2d4e5...  "Staging webhook"           Ніколи не використовувався            [Видалити]

Додати кнопку «Показати ключ» неможливо — він не зберігається. Тільки повторне створення.

Терміни

Таблиця api_keys, middleware перевірки, UI для створення/видалення ключів, обмеження частоти за ключем: 1–2 дні.