Reputation: 43
I am using Slim v3 with the CORS middleware at https://github.com/tuupola/cors-middleware to handle CORS headers. Everything works, however I now need to be able to modify the Access-Control-Allow-Origin header based on who a user is logging in as. I have another middleware that executes after the CORS middleware to do user verification, and I was hoping that from within this middleware I could just add $response = $response->withHeader('Access-Control-Allow-Origin', $userdomain) and it would keep the rest of the CORS headers set by the previous middleware, but override that one. However, this doesn’t seem to happen. No matter where this middleware executes, the CORS headers are always the ones defined by the CORS middleware.
The current setup looks like this:
$app->add(new \Internal\OAuth\Middleware($this->getDBs()));
$app->add(new \Tuupola\Middleware\Cors([
"origin" => ['*'],
"methods" => ['GET', 'POST', 'PUT', 'OPTIONS', 'DELETE'],
"headers.allow" => ['', 'Authorization', 'Content-Type', 'Content-Length', 'Origin', 'Accept'],
"credentials" => true,
"cache" => 100
]));
The \Internal\OAuth\Middleware __invoke looks like this:
public function __invoke($req, $res, $next) {
//do authentication stuff
$userdomain = 'http://blahblahblah';
$res = $res->withHeader('Access-Control-Allow-Origin', $userdomain);
return $next($req, $res);
}
Upvotes: 1
Views: 2456
Reputation: 216
Try it:
index.php
:
<?php
$app = new \Slim\App();
$app->add(new \Internal\OAuth\Middleware());
$app->get('/', function(\Psr\Http\Message\ServerRequestInterface $req, \Psr\Http\Message\ResponseInterface $res, $args) {
$res->getBody()->write(json_encode(['url' => $req->getUri()->__toString(), 'args'=>$args]));
return $res->withHeader('content-type', 'application/json');
});
$app->run();
src/Internal/OAuth/Middleware.php
<?php
namespace Internal\OAuth;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
class Middleware
{
/**
* @param ServerRequestInterface $req
* @param ResponseInterface $res
* @param callable $next
* @return ResponseInterface
*/
public function __invoke($req, $res, $next) {
//do authentication stuff
$options = [
"origin" => ['http://blahblahblah'],
"methods" => ['GET', 'POST', 'PUT', 'OPTIONS', 'DELETE'],
"headers.allow" => ['', 'Authorization', 'Content-Type', 'Content-Length', 'Origin', 'Accept'],
"credentials" => true,
"cache" => 100
];
$cors = new \Tuupola\Middleware\CorsMiddleware($options);
$handler = new Handler($res, $next);
$res = $cors->process($req, $handler);
return $res;
}
}
src/Internal/OAuth/Handler.php
<?php
namespace Internal\OAuth;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Server\RequestHandlerInterface;
class Handler implements RequestHandlerInterface
{
protected $callable;
protected $response;
public function __construct(ResponseInterface $response, callable $callable)
{
$this->callable = $callable;
$this->response = $response;
}
public function handle(ServerRequestInterface $request): ResponseInterface
{
$handler = $this->callable;
return $handler($request, $this->response);
}
}
Tests:
1.
curl "http://localhost:8088" --request OPTIONS --include --header "Origin: http://disallowed-host" --header "Access-Control-Request-Method: PUT"
HTTP/1.1 401 Unauthorized
Host: localhost:8088
Date: Tue, 04 Dec 2018 13:19:14 +0700
Connection: close
Content-Length: 0
2.
curl "http://localhost:8088" --request OPTIONS --include --header "Origin: http://blahblahblah" --header "Access-Control-Request-Method: PUT"
HTTP/1.1 200 OK
Host: localhost:8088
Date: Tue, 04 Dec 2018 13:19:04 +0700
Connection: close
Access-Control-Allow-Origin: http://blahblahblah
Access-Control-Allow-Credentials: true
Vary: Origin
Access-Control-Max-Age: 100
Access-Control-Allow-Methods: GET, POST, PUT, OPTIONS, DELETE
Content-Length: 0
Upvotes: 0
Reputation: 216
In the middleware you need to add a header AFTER the handler
<?php
namespase \Internal\OAuth;
class Middleware
{
public function __invoke($req, $res, $next) {
//do authentication stuff
$userdomain = 'http://blahblahblah';
$res = $next($req, $res);
return $res->withHeader('Access-Control-Allow-Origin', $userdomain);
}
}
Upvotes: 2