我在我的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);
有人能想出解决方法吗?
答案 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()
{
// ...
});