Enable CORS for specific domains

Hi there! :wave: :smiley:

I have a question. How do you manage CORS in Slim PHP?

I’m reading the documentation about setting up CORS:

https://www.slimframework.com/docs/v4/cookbook/enable-cors.html

The following code should enable CORS:


$app->options('/{routes:.+}', function ($request, $response, $args) {
    return $response;
});

$app->add(function ($request, $handler) {
    $response = $handler->handle($request);
    return $response
            ->withHeader('Access-Control-Allow-Origin', 'http://mysite')
            ->withHeader('Access-Control-Allow-Headers', 'X-Requested-With, Content-Type, Accept, Origin, Authorization')
            ->withHeader('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, PATCH, OPTIONS');
});

With for example:


// For one specific domain.
->withHeader('Access-Control-Allow-Origin', 'http://mysite.com')


// For any domain.
->withHeader('Access-Control-Allow-Origin', '*')

I’m wondering, what if I want to enable multiple domains? (but just my trustworthy domains, not all of them with ‘*’)

I tried with domains separated by commas, but I get an error like this:

(Running PHP 8.0.6 Built-In Web Server)


UPDATE:

While I’m writing this, I’m thinking of maintaining a list of available domains for CORS.
And if $_SERVER[‘HTTP_ORIGIN’] exists in this array of available domains, enable CORS for this specific domain.

(I think it should work, but maybe you know others way more simple -without using $_SERVER[‘HTTP_ORIGIN’]- :thinking: :slightly_smiling_face:)

Any thoughts?

Thank you in advance!

Checking the domain against a list is fine.

The “problem” is that HTTP_ORIGIN and HTTP_REFERER is neither sent by all browsers nor it is secure to trust.

Instead you could check the domain from the PSR-7 $reqest object.

// Returns "example.com"
$host = $request->getUri()->getHost();

Example with schema (http or https):

$allowList = [
    'https://example.com' => 1,
    'https://www.example.com' => 1,
];

$uri = $request->getUri();
$host = $uri->getScheme() . '://' . $uri->getHost();
$allowed = isset($allowList[$host]);

if ($allowed) {
    $response = $response->withHeader('Access-Control-Allow-Origin', '*');
    // ...
}
1 Like

Thanks! You are right.

I forget about the object $request.

I’ll use it that way…

Thank you very much, @odan.

1 Like

Hi @maurobonfietti

If you want a well tested solution: chubbyphp-cors/Slim4.md at master · chubbyphp/chubbyphp-cors · GitHub which also handle allowed methods, allow headers

I’ll take a look. :smiley: Thank you @dominik.zogg