CodeIgniter 4 过滤器 - 退出并有响应
CodeIgniter 4 Filter - exit with response
我有一个使用 CodeIgniter 4 的项目。
我有一个 before
过滤器:
public function before(RequestInterface $request){
$auth = $request->getHeader("Authorization");
if($auth == null){
$response = Services::response();
$response->setStatusCode(401);
$response->setHeader("WWW-Authenticate", "Bearer Token");
$response->setBody("{\"error\": \"unauthorized\"}");
exit;
}
}
如果没有授权,我想停止请求,return $response
给客户端
现在请求已停止,因为 exit
。
但作为答案,我得到 200 OK
而没有 body content
。
如何 exit
请求并将 $response
设置为客户端?
$response
在 before 方法中不可用:
所以我在之前的方法中执行了以下操作来发送响应并停止执行:
header('HTTP/1.1 401 Unauthorized', true, 401);
die(json_encode(['error' => 'Unauthorized']));
如评论中所述,在 Filter 的 before 方法中返回 Response 对象会阻止控制器的执行。您不需要使用 die
或 exit
.
public function before(RequestInterface $request){
$auth = $request->getHeader("Authorization");
if($auth == null){
$response = Services::response();
$response->setStatusCode(401);
$response->setHeader("WWW-Authenticate", "Bearer Token");
$response->setBody("{\"error\": \"unauthorized\"}");
return $response;
}
}
请注意,使用 return;
不返回任何内容不会从 运行 停止控制器。
使用sendBody方法打印响应内容。
public function before(RequestInterface $request){
$auth = $request->getHeader("Authorization");
if($auth == null){
$response = Services::response();
$response->setStatusCode(401);
$response->setHeader("WWW-Authenticate", "Bearer Token");
$response->setBody("{\"error\": \"unauthorized\"}");
$response->sendBody();
exit;
}
}
这已经晚了,但返回响应会阻止控制器的执行。
我在获取 axios 响应拦截器的 error.response
object 时在前端遇到了问题,并通过在下面添加 headers 解决了这个问题。
$response = Service::response()
->setContentType('application/json')
->setHeader('Access-Control-Allow-Origin', 'http:://yourdomain.com');
今天我亲身经历了这个过滤问题。我的情况如下(摘自App\Config\Filters
):
$globals
- CSRF 和过滤器 A
按照@ViLar 建议的方式过滤 A returns。
$filters
- 过滤器 B
过滤器 B 是一个通用过滤器,如果失败则重定向。
问题是,在我的实例中,我希望过滤器 B 仍然 运行 但作为过滤器 A returns 响应 - Codeigniter 停止处理。事实上,我希望过滤器 B 真的优先于过滤器 A。Codeigniter 编译了一个要应用的过滤器列表,但首先选择了 global,然后是 filters数组。
我的解决方案(我希望这对处于类似情况的任何人有所帮助)是编辑 System/Filters/Filters.php
(是的,这是一个有些人可能不喜欢的核心系统文件)和 initialize()
函数并将 $this->processFilters($uri);
移动到 $this->processGlobals($uri);
调用上方。
我有一个使用 CodeIgniter 4 的项目。
我有一个 before
过滤器:
public function before(RequestInterface $request){
$auth = $request->getHeader("Authorization");
if($auth == null){
$response = Services::response();
$response->setStatusCode(401);
$response->setHeader("WWW-Authenticate", "Bearer Token");
$response->setBody("{\"error\": \"unauthorized\"}");
exit;
}
}
如果没有授权,我想停止请求,return $response
给客户端
现在请求已停止,因为 exit
。
但作为答案,我得到 200 OK
而没有 body content
。
如何 exit
请求并将 $response
设置为客户端?
$response
在 before 方法中不可用:
所以我在之前的方法中执行了以下操作来发送响应并停止执行:
header('HTTP/1.1 401 Unauthorized', true, 401);
die(json_encode(['error' => 'Unauthorized']));
如评论中所述,在 Filter 的 before 方法中返回 Response 对象会阻止控制器的执行。您不需要使用 die
或 exit
.
public function before(RequestInterface $request){
$auth = $request->getHeader("Authorization");
if($auth == null){
$response = Services::response();
$response->setStatusCode(401);
$response->setHeader("WWW-Authenticate", "Bearer Token");
$response->setBody("{\"error\": \"unauthorized\"}");
return $response;
}
}
请注意,使用 return;
不返回任何内容不会从 运行 停止控制器。
使用sendBody方法打印响应内容。
public function before(RequestInterface $request){
$auth = $request->getHeader("Authorization");
if($auth == null){
$response = Services::response();
$response->setStatusCode(401);
$response->setHeader("WWW-Authenticate", "Bearer Token");
$response->setBody("{\"error\": \"unauthorized\"}");
$response->sendBody();
exit;
}
}
这已经晚了,但返回响应会阻止控制器的执行。
我在获取 axios 响应拦截器的 error.response
object 时在前端遇到了问题,并通过在下面添加 headers 解决了这个问题。
$response = Service::response()
->setContentType('application/json')
->setHeader('Access-Control-Allow-Origin', 'http:://yourdomain.com');
今天我亲身经历了这个过滤问题。我的情况如下(摘自App\Config\Filters
):
$globals
- CSRF 和过滤器 A
按照@ViLar 建议的方式过滤 A returns。
$filters
- 过滤器 B
过滤器 B 是一个通用过滤器,如果失败则重定向。
问题是,在我的实例中,我希望过滤器 B 仍然 运行 但作为过滤器 A returns 响应 - Codeigniter 停止处理。事实上,我希望过滤器 B 真的优先于过滤器 A。Codeigniter 编译了一个要应用的过滤器列表,但首先选择了 global,然后是 filters数组。
我的解决方案(我希望这对处于类似情况的任何人有所帮助)是编辑 System/Filters/Filters.php
(是的,这是一个有些人可能不喜欢的核心系统文件)和 initialize()
函数并将 $this->processFilters($uri);
移动到 $this->processGlobals($uri);
调用上方。