---
title: "Add JWT Authentication to Your undefined API"
description: undefined
canonicalUrl: "https://zuplo.com/use-cases/api-key-auth/php/fuelphp/jwt-backend"
framework: undefined
language: undefined
authStrategy: "JWT with JWKS"
pageType: use-case
---

# Add JWT Authentication to Your undefined API



## How Zuplo Handles It

Let Zuplo issue short-lived JWTs signed with a JWKS your undefined backend can verify — no long-lived API keys touch your origin.

## undefined Backend Code

```php
use Firebase\JWT\JWT;
use Firebase\JWT\JWK;
use Fuel\Core\Input;
use Fuel\Core\Response;
use Fuel\Core\Route;

// Define JWKS URI and issuer
define('ISSUER', 'https://my-api-a32f34.zuplo.api/__zuplo/issuer');
define('JWKS_URI', ISSUER . '/.well-known/jwks.json');

// Fetch JWKS from issuer
function fetchJwks()
{
    try {
        $content = file_get_contents(JWKS_URI);
        return json_decode($content, true);
    } catch (Exception $e) {
        return null;
    }
}

// Middleware to validate JWT
function validateJwt($route, $params)
{
    $authHeader = Input::headers('Authorization');
    $token = str_replace('Bearer ', '', $authHeader);

    if (!$token) {
        return Response::forge(json_encode(['error' => 'No token provided']), 401);
    }

    $jwks = fetchJwks();
    if (!$jwks) {
        return Response::forge(json_encode(['error' => 'Unable to fetch JWKS']), 500);
    }

    try {
        $decoded = JWT::decode($token, JWK::parseKeySet($jwks), ['RS256']);
        if ($decoded->iss !== ISSUER) {
            throw new Exception('Invalid issuer');
        }

        Route::add_filter('auth', function() use ($decoded) {
            // Store decoded user information
            $_SESSION['user'] = $decoded;
        });

    } catch (Exception $e) {
        return Response::forge(json_encode(['error' => 'Invalid token', 'details' => $e->getMessage()]), 401);
    }
}

// Example route with JWT protection
Route::add('/protected', function() {
    validateJwt();

    return Response::forge(json_encode([
        'message' => 'Access granted',
        'user' => $_SESSION['user'],
    ]));
});

// Ensure all routes pass through JWT validation
Route::add_before('validateJwt');
```

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