Laravel路由过滤器未更新响应

时间:2014-02-07 16:32:46

标签: php laravel laravel-4

我在我的API(Laravel 4.1。*应用)中使用了lucadegasperi/oauth2-server-laravel包for OAuth,它提供了一个过滤器,可以在运行这样的路由之前轻松验证授权:

Route::group(array('prefix' => 'api', 'before' => 'oauth:auth'), function() {
   // My API Routes
});

它返回的JSON响应不符合我在API中使用的格式,并希望将其更改为一致。所以我在 filters.php 中创建了一个过滤器,并将其设置为过滤器。

Route::group(array('prefix' => 'core', 'before' => 'oauth:auth', 'after' => 'oauth.cleanresponse'), function() {
   // My API Routes
)};

过滤器:

/**
* OAuth Package returns JSON response in custom format that is not consistent with
* Core API output. We need to alter the output to fit the standard response.
*/
Route::filter('oauth.cleanresponse', function($request, $response) {

   if ($response instanceof Illuminate\Http\JsonResponse)
   {
      $responseData = $response->getData();
      if (isset($responseData->error_message));
      {
        $newResponse = new API\ApiResponse();
        $newResponse->setError($responseData->error_message);
        $newResponse->setCode($responseData->status);
        return Response::json($newResponse->error(), $responseData->status);      
      }
   }

   });

过滤器运行正常,我可以在返回之前var_dump()更改我的更改。

但是,响应中API调用返回的值不是我的新值,它仍然是oauth库在之前过滤器中创建的原始值。

TL; DR;为什么来自之后过滤器的响应不会覆盖之前过滤器的响应,我该如何解决此问题?

注意:我不想编辑OAuth包,因为只要我执行composer update,它就可能会覆盖我的更改。

修改

仔细检查Laravel路由器( Illuminate / Routing / Router.php )有:

/**
 * Dispatch the request to a route and return the response.
 *
 * @param  \Illuminate\Http\Request  $request
 * @return mixed
 */
public function dispatchToRoute(Request $request)
{
    $route = $this->findRoute($request);

    $this->events->fire('router.matched', array($route, $request));

    // Once we have successfully matched the incoming request to a given route we
    // can call the before filters on that route. This works similar to global
    // filters in that if a response is returned we will not call the route.
    $response = $this->callRouteBefore($route, $request);

    if (is_null($response))
    {
        $response = $route->run($request);
    }

    $response = $this->prepareResponse($request, $response);

    // After we have a prepared response from the route or filter we will call to
    // the "after" filters to do any last minute processing on this request or
    // response object before the response is returned back to the consumer.
    $this->callRouteAfter($route, $request, $response);

    return $response;
}

如果之前过滤器返回结果,然后调用之后过滤器,则会阻止调度请求。问题是它没有捕获响应!看来这个:

$this->callRouteAfter($route, $request, $response);

应该是这样的(虽然这不起作用):

$response = $this->callRouteAfter($route, $request, $response);

有人能想出解决方法吗?

2 个答案:

答案 0 :(得分:1)

您必须使用

在当前实例中设置响应
$json = 'prepare the json here';
// set and return response with new data
return $response->setContent($json);

答案 1 :(得分:0)

“之后”过滤器有3个参数,而不是2:路由,请求和响应(“之前”过滤器只有2:路由和请求,因为在该阶段没有响应。)

在您的代码中,您的后置过滤器功能只有两个参数,因此$request包含Route,而您的$response包含请求。您需要添加$route作为第一个参数。

之后,您可以调用$response->header()$response->setContent()来修改生成的响应。

“之后”过滤器无法返回新的$response,它们只能修改传递给它们的过滤器。

示例工作代码:

Route::filter('api_headers', function($route, $request, $response) {
    $response->header('Access-Control-Allow-Origin', '*');
    $response->header('P3P', 'CP="IDC DSP COR CURa ADMa OUR IND PHY ONL COM STA"');
});
Route::group(array('prefix'=>'api', 'after'=>'api_headers'), function()
{
    // ...
});