---
title: "Secure CakePHP APIs with API Key Authentication"
description: "Secure your CakePHP API using a shared secret."
canonicalUrl: "https://zuplo.com/use-cases/api-key-auth/php/cakephp/secure-header"
framework: "CakePHP"
language: "PHP"
authStrategy: "shared secret header"
pageType: use-case
---

# Secure CakePHP APIs with API Key Authentication

Secure your CakePHP API using a shared secret.

## How Zuplo Handles It

Put Zuplo in front of your CakePHP backend to authenticate API keys and forward a shared secret header so your origin only accepts traffic from Zuplo.

## CakePHP Backend Code

```php
// src/Middleware/SharedSecretMiddleware.php

namespace App\Middleware;

use Cake\Http\Response;
use Cake\Http\Exception\UnauthorizedException;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Server\RequestHandlerInterface;
use Psr\Http\Message\ServerRequestInterface;
use Cake\Core\Configure;
use Exception;

class SharedSecretMiddleware
{
    public function __invoke(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface
    {
        $secretHeader = $request->getHeaderLine('X-Shared-Secret');
        $expectedSecret = Configure::read('Security.sharedSecret');

        if (empty($expectedSecret)) {
            throw new Exception('Server configuration error: Shared secret not set.');
        }

        if (empty($secretHeader)) {
            throw new UnauthorizedException('No secret provided.');
        }

        if (!$this->timingSafeCompare($secretHeader, $expectedSecret)) {
            throw new UnauthorizedException('Invalid secret.');
        }

        return $handler->handle($request);
    }

    private function timingSafeCompare(string $safe, string $user): bool
    {
        if (mb_strlen($safe, '8bit') !== mb_strlen($user, '8bit')) {
            return false;
        }

        $result = 0;
        for ($i = 0; $i < mb_strlen($safe, '8bit'); $i++) {
            $result |= (ord($safe[$i]) ^ ord($user[$i]));
        }
        return $result === 0;
    }
}
```

## Example Request

```bash
curl -X GET \
  'https://your-api.zuplo.dev/your-route' \
  -H 'Authorization: Bearer YOUR_API_KEY'
```

## Learn More

- [API Key Authentication on Zuplo](https://zuplo.com/docs/policies/api-key-auth-inbound)
- [JWT Authentication on Zuplo](https://zuplo.com/docs/policies/open-id-jwt-auth-inbound)
- [All use cases](https://zuplo.com/use-cases)
