CI4 Playground v4.7.3
한국어문서
API 키 발급
bin2hex(random_bytes(32))로 64자 랜덤 키를 생성합니다.
보호된 엔드포인트 테스트

GET /examples/apiauth/protectedapi-key 필터가 적용된 보호 엔드포인트입니다. 아래에 발급된 키를 붙여넣고 테스트하세요.


                        
발급된 API 키 목록
ID 이름 API 키 상태 마지막 사용 발급일 관리
2 gfdgfdgfd 85ad9316532fde7c... 활성 2026-05-27 14:26:29 2026-05-27 13:30:44
1 샘플 API 키 (데모용) 41a98d59abae13b2... 활성 - 2026-05-27 13:21:08
app/Filters/ApiKeyFilter.php
namespace App\Filters;

use CodeIgniter\Filters\FilterInterface;
use CodeIgniter\HTTP\RequestInterface;
use CodeIgniter\HTTP\ResponseInterface;

class ApiKeyFilter implements FilterInterface
{
    public function before(RequestInterface $request, $arguments = null)
    {
        $authHeader = $request->getHeaderLine('Authorization');

        // Authorization: Bearer {api_key} 헤더 검증
        if (empty($authHeader) || ! str_starts_with($authHeader, 'Bearer ')) {
            return service('response')
                ->setStatusCode(401)
                ->setJSON(['error' => 'Unauthorized', 'message' => '헤더가 필요합니다.']);
        }

        $apiKey = trim(substr($authHeader, 7));

        $db  = \Config\Database::connect();
        $row = $db->table('api_keys')->where('api_key', $apiKey)->get()->getRowArray();

        if (! $row) {
            return service('response')
                ->setStatusCode(401)
                ->setJSON(['error' => 'Invalid API Key']);
        }

        if (! $row['is_active']) {
            return service('response')
                ->setStatusCode(403)
                ->setJSON(['error' => 'Forbidden', 'message' => '비활성화된 키']);
        }

        // 통과 시 last_used_at 업데이트
        $db->table('api_keys')
            ->where('id', $row['id'])
            ->update(['last_used_at' => date('Y-m-d H:i:s')]);
    }

    public function after(RequestInterface $request, ResponseInterface $response, $arguments = null) {}
}
필터 등록 (Config/Filters.php)
// app/Config/Filters.php
public array $aliases = [
    // ...기존 필터들
    'api-key' => \App\Filters\ApiKeyFilter::class,
];
라우트에 필터 적용 (Routes.php)
// 단일 라우트에 적용
$routes->get('apiauth/protected',
    'Examples\ApiAuth::protected',
    ['filter' => 'api-key']
);

// 그룹 전체에 적용
$routes->group('api/v1', ['filter' => 'api-key'],
    function($routes) {
        $routes->get('users',  'Api\Users::index');
        $routes->post('users', 'Api\Users::create');
    }
);
클라이언트에서 사용하는 방법
curl
curl -H "Authorization: Bearer YOUR_API_KEY" \
     https://example.com/api/v1/users
JavaScript fetch
const response = await fetch('/api/v1/users', {
    headers: {
        'Authorization': 'Bearer ' + apiKey,
        'Content-Type':  'application/json',
    }
});
PHP (CI4 CURLRequest)
$client   = \Config\Services::curlrequest();
$response = $client->get('https://api.example.com/users', [
    'headers' => [
        'Authorization' => 'Bearer ' . $apiKey,
    ],
]);
응답 코드 규칙: 200 인증 성공 / 401 키 없음·유효하지 않음 / 403 키 비활성화