我想我看到了这段代码的问题。
use Psr\Http\Message\ServerRequestInterface as Request;
use Psr\Http\Message\ResponseInterface as Response;
use Psr\Http\Server\RequestHandlerInterface as RequestHandler;
class AuthMiddleware extends Middleware {
public function __invoke(Request $request, RequestHandler $handler): Response {
$response = $handler->handle($request);
$loggedInTest = false;
if ($loggedInTest) {
echo "User authorized.";
return $response;
} else {
echo "User NOT authorized.";
return $response->withHeader('Location', '/users/login')->withStatus(302);
}
}
}
当您调用$handler->handle($request)
时,它会正常处理请求并调用任何应该处理路由的闭包。响应尚未完成,您仍然可以向其附加内容,但标头已设置,因此您无法进行重定向,因为标头已完成。
也许试试这个:
use Psr\Http\Message\ServerRequestInterface as Request;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Server\RequestHandlerInterface as RequestHandler;
use Slim\Psr7\Response;
class AuthMiddleware extends Middleware {
public function __invoke(Request $request, RequestHandler $handler): ResponseInterface {
$loggedInTest = false;
if ($loggedInTest) {
$response = $handler->handle($request);
echo "User authorized.";
return $response;
} else {
$response = new Response();
// echo "User NOT authorized.";
return $response->withHeader('Location', '/users/login')->withStatus(302);
}
}
}
如果登录测试失败,我们永远不会调用$handler->handle()
,因此不会生成正常响应。同时,我们创造了一个新的回应。
请注意,ResponseInterface
andResponse
不能Response
在同一个文件中同时调用,因此我必须删除该别名,而只需ResponseInterface
使用其真实名称调用。你可以给它一个不同的别名,但我认为这只会造成更多的混乱。
另外,我在重定向之前注释掉了回声。我认为这个回声会强制标头自动发送,这会破坏重定向。除非 Slim 4 正在做输出缓冲,在这种情况下你仍然看不到它,因为重定向会立即将你发送到不同的页面。无论如何,我将其注释掉以使代码有最好的工作机会,但将其保留以供参考。
无论如何,我认为如果你做出那么小的改变,一切都会奏效。当然,这篇文章已经快一年了,所以你可能已经自己解决了这个问题,切换到 F3,或者现在放弃了这个项目。但希望这对其他人有帮助。这就是 StackOverflow 的重点,对吧?