First of all, do not access superglobals in CakePHP directly, always use the abstracted APIs! Also you shouldn't echo data manually, that includes headers, again, use the abstracted APIs! Using superglobals and echoing data will only get you in trouble, it messes up the testing environment, it can lead to data not being sent (properly), etc.
That being said, for proper CORS coverage you also need to modify error handling, as the error controller will create a new response instance. You should be able to process the request/response in a custom exception renderer, at ExceptionRenderer::_getController()
, like so:
// in src/Error/AppExceptionRenderer.php
namespace AppError;
use AppHttpMiddlewareCorsMiddleware;
use CakeControllerController;
use CakeErrorExceptionRenderer;
class AppExceptionRenderer extends ExceptionRenderer
{
protected function _getController(): Controller
{
$controller = parent::_getController();
$cors = new CorsMiddleware();
$response = $cors->setHeaders(
$controller->getRequest(),
$controller->getResponse()
);
return $controller->setResponse($response);
}
}
// in config/app.php
'Error' => [
'exceptionRenderer' => AppErrorAppExceptionRenderer::class,
// ...
],
Your CORS middleware would supply the setHeaders()
method accordingly, where you set the CORS headers if required, based on your example it could look something like this:
public function process(
ServerRequestInterface $request,
RequestHandlerInterface $handler
): ResponseInterface
{
$response = $handler->handle($request);
$response = $this->setHeaders($request, $response);
return $response;
}
public function setHeaders(
ServerRequestInterface $request,
ResponseInterface $response
): ResponseInterface
{
if ($request->getHeader('Origin')) {
$allowedDomains = [
'https://myapp.it',
'https://www.myapp.it',
'http://localhost:3000',
];
$origins = $request->getHeader('Origin');
$lastOrigin = end($origins);
if (in_array($lastOrigin, $allowedDomains, true)) {
$response = $response
->withHeader('Access-Control-Allow-Origin', $lastOrigin);
}
if (strtoupper($request->getMethod()) === 'OPTIONS') {
$response = $response
->withHeader(
'Access-Control-Allow-Methods',
'POST, GET, PUT, PATCH, DELETE, OPTIONS'
)
->withHeader('Access-Control-Allow-Headers', '*');
}
}
return $response;
}
See also