如何从 Slim 4 中间件进行重定向?

Con*_*eeC 4 php response.redirect psr-7 slim-4

我一直在测试新的 Slim 4 框架,并且重定向在普通类中对我来说工作得很好,但我似乎无法让它们在中间件中工作,中间件中的响应是由请求处理程序动态生成的(显然?)。当我尝试使用 Location 标头进行重定向时,它根本无法重定向,并且我的路线继续到原始位置。

\n\n

这里\xe2\x80\x99是我用于测试的身份验证中间件的基本版本:

\n\n
use Psr\\Http\\Message\\ServerRequestInterface as Request;\nuse Psr\\Http\\Message\\ResponseInterface as Response;\nuse Psr\\Http\\Server\\RequestHandlerInterface as RequestHandler;\n\nclass AuthMiddleware extends Middleware {\n\n    public function __invoke(Request $request, RequestHandler $handler): Response {\n        $response = $handler->handle($request);\n        $loggedInTest = false;\n        if ($loggedInTest) {\n            echo "User authorized.";\n            return $response;\n        } else {\n            echo "User NOT authorized.";\n            return $response->withHeader(\'Location\', \'/users/login\')->withStatus(302);\n        }\n    }\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

有人让这个工作吗?如果是这样,你是如何实现的?提前致谢。

\n

eim*_*hat 7

我想我看到了这段代码的问题。

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);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

当您调用 时$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);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

如果登录测试失败,我们永远不会调用$handler->handle(),因此不会生成正常响应。同时,我们创建一个新的响应。

请注意,不能在同一个文件中同时调用 和ResponseInterface,因此我必须删除该别名,然后仅按其真实名称来调用 。您可以给它一个不同的别名,但我认为这只会造成更多混乱。ResponseResponseResponseInterface

另外,我在重定向之前注释掉了 echo。我认为这个回显将强制自动发送标头,这将破坏重定向。除非 Slim 4 正在进行输出缓冲,在这种情况下您仍然看不到它,因为重定向会立即将您发送到不同的页面。无论如何,我将其注释掉,以便为代码提供最佳的工作机会,但将其保留在适当的位置以供参考。

无论如何,我认为如果你做出一点点改变,一切都会成功。当然,这篇文章已经快一年了,所以你可能已经自己解决了这个问题,切换到 F3,或者现在放弃了该项目。但希望这对其他人有帮助。这就是 StackOverflow 的全部意义,对吗?