无法在 Slim Framework 中覆盖 CORS headers
Cannot override CORS headers in Slim Framework
我在 https://github.com/tuupola/cors-middleware 使用带有 CORS 中间件的 Slim v3 来处理 CORS header。一切正常,但我现在需要能够根据用户登录身份修改 Access-Control-Allow-Origin header。我有另一个在 CORS 中间件之后执行的中间件来进行用户验证,我希望从这个中间件中我可以添加 $response = $response->withHeader('Access-Control-Allow-Origin', $userdomain) 它会保持由前一个中间件设置的其余 CORS headers,但覆盖那个。然而,这似乎并没有发生。无论此中间件在何处执行,CORS header 始终由 CORS 中间件定义。
当前设置如下所示:
$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
]));
\Internal\OAuth\Middleware __invoke 看起来像这样:
public function __invoke($req, $res, $next) {
//do authentication stuff
$userdomain = 'http://blahblahblah';
$res = $res->withHeader('Access-Control-Allow-Origin', $userdomain);
return $next($req, $res);
}
在中间件中,您需要在处理程序
之后添加一个header
<?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);
}
}
试一试:
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);
}
}
测试:
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
我在 https://github.com/tuupola/cors-middleware 使用带有 CORS 中间件的 Slim v3 来处理 CORS header。一切正常,但我现在需要能够根据用户登录身份修改 Access-Control-Allow-Origin header。我有另一个在 CORS 中间件之后执行的中间件来进行用户验证,我希望从这个中间件中我可以添加 $response = $response->withHeader('Access-Control-Allow-Origin', $userdomain) 它会保持由前一个中间件设置的其余 CORS headers,但覆盖那个。然而,这似乎并没有发生。无论此中间件在何处执行,CORS header 始终由 CORS 中间件定义。
当前设置如下所示:
$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
]));
\Internal\OAuth\Middleware __invoke 看起来像这样:
public function __invoke($req, $res, $next) {
//do authentication stuff
$userdomain = 'http://blahblahblah';
$res = $res->withHeader('Access-Control-Allow-Origin', $userdomain);
return $next($req, $res);
}
在中间件中,您需要在处理程序
之后添加一个header<?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);
}
}
试一试:
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);
}
}
测试:
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