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

Php 如何从Slim 4中间件进行重定向?,php,response.redirect,psr-7,slim-4,Php,Response.redirect,Psr 7,Slim 4,我一直在测试新的Slim 4框架,重定向在普通类中运行良好,但我似乎无法让它们在中间件中运行,在中间件中,响应是由请求处理程序动态生成的(显然是?)。当我尝试使用位置头重定向时,它根本无法重定向,并且我的路由继续到原始位置 以下是用于测试的身份验证中间件的基本版本: 使用Psr\Http\Message\ServerRequestInterface作为请求; 使用Psr\Http\Message\ResponseInterface作为响应; 使用Psr\Http\Server\RequestHa

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

以下是用于测试的身份验证中间件的基本版本:

使用Psr\Http\Message\ServerRequestInterface作为请求;
使用Psr\Http\Message\ResponseInterface作为响应;
使用Psr\Http\Server\RequestHandler接口作为RequestHandler;
类AuthMiddleware扩展了中间件{
公共函数调用(Request$Request,RequestHandler$handler):响应{
$response=$handler->handle($request);
$loggedInTest=false;
如果($loggedInTest){
echo“用户授权”;
返回$response;
}否则{
echo“用户未授权。”;
返回$response->withHeader('Location','/users/login')->with status(302);
}
}
}

有人用这个吗?如果是这样,你是如何做到的?提前感谢。

我对Slim 4和重定向问题感到非常沮丧,因此我查看了FatFreeFramework,发现了完全相同的问题。所以我知道这是我在做的事情。我的代码将应用程序放入一个永无止境的重定向循环中。我可以通过在FatFreeFramework中验证重定向URL使其正常工作:

class Controller {

    protected $f3;

    public function __construct() {
        $isLoggedIn = false;
        $this->f3 = Base::instance();
        if ($isLoggedIn == false && $_SERVER['REQUEST_URI'] != '/login') {
            $this->f3->reroute('/login');
            exit();
        }
    }
}

因此,尽管我实际上没有花时间测试它,但我假设我可以通过如下操作在Slim 4中修复它:

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 && $_SERVER['REQUEST_URI'] != '/user/login') {
            return return $response->withHeader('Location', '/users/login')->withStatus(302);
        } else {
            return $response;
        }
    }
}
有人对如何打破连续重定向循环有其他想法吗?或者$\u服务器变量是最佳选项


提前感谢。

我对Slim 4和重定向问题感到非常沮丧,因此我查看了FatFreeFramework,发现了完全相同的问题。所以我知道这是我在做的事情。我的代码将应用程序放入一个永无止境的重定向循环中。我可以通过在FatFreeFramework中验证重定向URL使其正常工作:

class Controller {

    protected $f3;

    public function __construct() {
        $isLoggedIn = false;
        $this->f3 = Base::instance();
        if ($isLoggedIn == false && $_SERVER['REQUEST_URI'] != '/login') {
            $this->f3->reroute('/login');
            exit();
        }
    }
}

因此,尽管我实际上没有花时间测试它,但我假设我可以通过如下操作在Slim 4中修复它:

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 && $_SERVER['REQUEST_URI'] != '/user/login') {
            return return $response->withHeader('Location', '/users/login')->withStatus(302);
        } else {
            return $response;
        }
    }
}
有人对如何打破连续重定向循环有其他想法吗?或者$\u服务器变量是最佳选项


提前谢谢。

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

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
Response
不能在同一个文件中同时调用
Response
,因此我必须删除该别名,只需按其真实名称调用
ResponseInterface
。你可以给它一个不同的别名,但我认为这只会造成更多的混乱

另外,我在重定向之前注释掉了echo。我认为这个回音将强制自动发送头,这将破坏重定向。除非Slim 4正在执行输出缓冲,否则您仍然无法看到它,因为重定向会立即将您发送到另一个页面。无论如何,我对它进行了注释,以使代码有最好的工作机会,但保留了它以供参考


不管怎么说,我想如果你做些小小的改变,一切都会好起来的。当然,这篇文章已经有将近一年的历史了,所以你可能已经自己解决了这个问题,换成了F3,或者现在就放弃了这个项目。但希望这能对其他人有所帮助。这就是StackOverflow的全部要点,对吗?

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

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
Response
不能在同一个文件中同时调用
Response
,因此我必须删除该别名,只需按其真实名称调用
ResponseInterface
。你可以给它一个不同的别名,但我认为这只会造成更多的混乱

另外,我在重定向之前注释掉了echo。我认为这个回音将强制自动发送头,这将破坏重定向。除非Slim 4正在执行输出缓冲,否则您仍然无法看到它,因为重定向会立即将您发送到另一个页面。无论如何,我对它进行了注释,以使代码有最好的工作机会,但保留了它以供参考

不管怎么说,我想如果你做些小小的改变,一切都会好起来的。当然,这篇文章已经有将近一年的历史了,所以你可能已经自己解决了这个问题,换成了F3,或者现在就放弃了这个项目。但希望这能对其他人有所帮助。这就是StackOverflow的全部要点,对吗?

是正确的,只是您不能创建接口的实例

请尝试以下方法:

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): Response {            
    global $app; // Assuming $app is your global object

    $loggedInTest = false;
    if ($loggedInTest) {
        $response = $handler->handle($request);
        echo "User authorized.";
        return $response;
    } else {
        $response = $app->getResponseFactory()->createResponse();
        // echo "User NOT authorized.";
        return $response->withHeader('Location', '/users/login')->withStatus(302);
    }
}
}

是正确的,只是您不能创建接口的实例

请尝试以下方法:

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): Response {            
    global $app; // Assuming $app is your global object

    $loggedInTest = false;
    if ($loggedInTest) {
        $response = $handler->handle($request);
        echo "User authorized.";
        return $response;
    } else {
        $response = $app->getResponseFactory()->createResponse();
        // echo "User NOT authorized.";
        return $response->withHeader('Location', '/users/login')->withStatus(302);
    }
}

}

说话太早了。长话短说,在我的FatFreeFramework测试中,我肯定是把我的测试应用程序放在