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

# Secure Yii2 APIs with API Key Authentication

Secure your Yii2 API using a shared secret.

## How Zuplo Handles It

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

## Yii2 Backend Code

```php
namespace app\components;

use Yii;
use yii\base\ActionFilter;
use yii\web\ForbiddenHttpException;
use yii\web\ServerErrorHttpException;

class SharedSecretFilter extends ActionFilter
{
    public function beforeAction($action)
    {
        $secret = Yii::$app->request->headers->get('x-shared-secret');
        $expectedSecret = getenv('SHARED_SECRET');

        if ($expectedSecret === false) {
            throw new ServerErrorHttpException('Server configuration error');
        }

        if (empty($secret)) {
            throw new ForbiddenHttpException('No secret provided');
        }

        if (!$this->timingSafeEquals($secret, $expectedSecret)) {
            throw new ForbiddenHttpException('Invalid secret');
        }

        return parent::beforeAction($action);
    }

    private function timingSafeEquals($a, $b)
    {
        if (strlen($a) !== strlen($b)) {
            return false;
        }

        $res = $a ^ $b;
        $ret = 0;

        for ($i = strlen($res) - 1; $i >= 0; $i--) {
            $ret |= ord($res[$i]);
        }

        return $ret === 0;
    }
}

// Configuring the filter in a controller
namespace app\controllers;

use yii\web\Controller;
use app\components\SharedSecretFilter;

class SiteController extends Controller
{
    public function behaviors()
    {
        return [
            'sharedSecretFilter' => [
                'class' => SharedSecretFilter::className(),
            ],
        ];
    }

    public function actionProtected()
    {
        return $this->asJson([
            'message' => 'Access granted',
        ]);
    }
}
```

## 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)
