【问题标题】:SLIM FRAMEWORK 3: Can't pass variable from middleware to controllerSLIM FRAMEWORK 3:无法将变量从中间件传递到控制器
【发布时间】:2018-08-18 07:40:06
【问题描述】:

我的代码有什么问题?我无法将变量从我的 Auth 中间件传递给控制器​​。在控制器中,属性“null”。

索引:

$c = new \Slim\Container($configuration);
$api = new \Slim\App($c);

$api->group('/', function () use ($api) {
$this->post('login', '\AuthController:login');
...
$this->post('getIngredientsCategories', '\IngredientsController:getIngredientsCategories');


})->add(new ApiAuthenticateController());

$api->run();

中间件(ApiAuthenticateController)

use \Firebase\JWT\JWT;

class ApiAuthenticateController
{
public function __invoke($request, $response, $next)
{
    $jwtDecoded = null;
    $req = $request->getUri()->getPath();
    $_req = RequestValidatorController::isRequestEnabled($req);

    if ($_req !== false) {
        if ($_req['login_required']) {
            $jwt = filter_var($request->getHeaderLine('AUTHORIZATION'), FILTER_SANITIZE_STRING);
            $jwt = explode(" ", $jwt)[1];
            try {
                $jwtDecoded = JWT::decode($jwt, JWT_SECRET, array('HS256'));
            } catch (\Exception $e) {
                return $this->deny_access($response);
            }
        }
        $request = $request->withAttribute('foo', $jwtDecoded);
        //HERE - attribute "foo" in $request exists - checked by var_dump()..
        $response = $next($request, $response);
        $response = $response->withHeader('Content-type', 'application/json');
        return $response;

    } else {
        return $this->deny_access($response);
    }
}

配料控制器

class IngredientsController extends Controller
{
  private $_ingredients;

  public function __construct(\Interop\Container\ContainerInterface $container)
  {
      parent::__construct($container);
  }
}

控制器

class Controller
{
  private $request;
  private $response;
  protected $data;
  protected $method;
  protected $user;

  public function __construct(Interop\Container\ContainerInterface $container)
  {
     $this->request = $container->get('request');
     $this->response = $container->get('response');
     $this->data = (object)Tools::stripInput($this->request->getParsedBody());
     $this->method = $this->request->getUri()->getPath();
     $this->user = $this->request->getAttribute('foo');
     var_dump($this->user);
     // returns NULL. if $this->request->getAttributes()... returns empty
 }
}

请注意,为了提高可读性,该代码已被“清理”,某些功能和条件已被删除。代码正在运行 - 抱歉可能有错别字。

【问题讨论】:

  • 问题很简单,您正在返回响应,而不是将其传递给下一个响应处理程序,您应该接受下面的答案;)
  • 我改了,但问题没有解决,结果没有改变......正如我在下面评论的那样

标签: php middleware slim-3


【解决方案1】:

问题出在这里

在中间件 ApiAuthenticateController 中,你应该像这样更改代码

$request = $request->withAttribute('foo', $jwtDecoded);
// you should return the $next here not to do anything else
return $next($request, $response);

在您的 IngredientsController:getIngredientsCategories 部分代码中,您应该返回

function getIngredientsCategories ($request, $response, $args){

    //do your job...
    $response = $response->withHeader('Content-type', 'application/json');
    return $response;

}

最后,在构造函数中,我认为在中间件之后没有实际的 $request,所以你的 getIngredientsCategories 函数中有 $this->request->getAttributes()

希望对你有帮助。

【讨论】:

  • 感谢您的回复。在我的 getIngredientsCategories 函数中调用 $this->request->getAttributes() 没有结果。仅当我在 getIngredientsCategories 函数中调用 $request->getAttributes() 时,该函数是函数参数 ($request, $response, $args) 之一。我需要在所有方法(+许多项目类)中访问对象用户,所以如果能在我的构造函数中获取这个对象(用户)并全局设置它会更好。
  • 全局控制器的构造函数中可以访问标题,但不能访问属性
猜你喜欢
  • 2017-09-10
  • 2021-10-12
  • 1970-01-01
  • 1970-01-01
  • 2015-11-20
  • 2017-06-14
  • 1970-01-01
  • 1970-01-01
  • 2020-02-17
相关资源
最近更新 更多