【发布时间】:2010-11-09 05:00:30
【问题描述】:
在我的控制器中,我检查一个条件以查看是否允许用户做某事。如果检查失败,我想将 403 发送回浏览器。我如何在 Cakephp 中做到这一点?
【问题讨论】:
-
另外值得注意的是,CakePHP 3x 符合PSR-7。
标签: cakephp
在我的控制器中,我检查一个条件以查看是否允许用户做某事。如果检查失败,我想将 403 发送回浏览器。我如何在 Cakephp 中做到这一点?
【问题讨论】:
标签: cakephp
EDIT - 这个问题很老了,涵盖了不同版本的 CakePHP 框架。以下是每个答案适用于哪个版本的摘要。不要忘记对最有帮助的解决方案进行投票。
EDIT #2 - Mark37 添加了用于 CakePHP 2.x 的 more detailed answer。
EDIT #3 - 添加了 CakePHP 的解决方案。 (2018 年 5 月:CakePHP 3.5 做了一些函数重命名,solution by Roberto 仍然有效。)
通过查看上一条评论中的相关API code,您似乎可以调用Controller::header($status) 来输出标头而无需重定向。在您的情况下,最有可能正确使用:
$this->header('HTTP/1.1 403 Forbidden');
【讨论】:
return false、die、exit或类似的东西结束执行。
$this->response->statusCode(403);
将在 Cake 准备好发送响应时设置状态码。 CakeResponse::send() 期望发送状态码和消息,所以在我的测试中,我认为我的使用 header() 被覆盖了。使用 $this->header('HTTP/1.1 400 Bad Request') 也不起作用,因为 Cake 期望对 $this->header 的任何调用都以冒号分隔:$this->header('Location: ...')
【讨论】:
$this->response->...),这可能有助于来自 Google 等的当前访问者。(对于那些访问者:2009 年的答案适用于 CakePHP 1.x 代码库)
在 CakePHP 2 中,preferred method 是 throw an exception:
throw new ForbiddenException();
【讨论】:
cakephp 3.6,但此代码未使用error403.ctp 模板。如何从ForbiddenException()设置error403.ctp模板
关于 CakePHP 3.x 的注释似乎丢失了,所以为了完成这个线程:
对于 CakePHP 3.x 和 4.x 使用:
$response = $this->response->withStatus(403);
return $response;
对于 CakePHP 3.3.x 之前的版本,您可以使用与 CakePHP 2.x 相同的样式:
$this->response->statusCode('code');
请注意,直接使用 PHP 函数 (http_response_code(403); die();) 也可以,尽管使用 response object 似乎是预期的方法。
【讨论】:
return $this->response->withStatus(403); 也适用于 CakePHP 4.x:api.cakephp.org/4.1/class-Cake.Http.Response.html#withStatus
ErrorController 可能会启动。
我在这里加两分钱,因为我觉得这些答案中的任何一个都没有像我希望的那样彻底涵盖这个主题(至少对于 Cake 2.x)。
如果您想抛出错误状态,请使用异常类(如其他答案中所述):
throw new BadRequestException(); // 400 Bad Request
// Or customize the code...
throw new BadRequestException('Custom error message', 405); // 405 Method Not Allowed
有趣的事实:即使是通过 ExceptionRenderer 类的 RESTful 调用,Cake 也会自动进行一些神奇的错误渲染。更有趣的事实是它基于状态码,而不是Exception 可能被抛出的事实,所以如果你自己将状态码设置为> 400,你会即使您不想要它们,也可能会收到错误消息。
如果您想为 REST JSON/XML 端点返回特定状态代码,请利用新的 CakeResponse 对象,但还要确保添加特殊的 _serialize 变量,否则您最终会得到一个“未找到视图”错误,因为 cake 将尝试找到一个视图来呈现您的 JSON/XML。 (这是设计使然 - 请参阅 JsonView/XmlView 类。)
$this->response->setStatus(201); // 201 Created
$this->set('_serialize', array()); // Value must be something other than null
最后,如果您想为定期呈现的页面发送非 200 状态,您可以只使用 setStatus() 方法,如上一个答案中所述:
$this->response->setStatus(201);
更新:
$this->response->setStatus('code');
不再可用。使用
$this->response->statusCode('code');
【讨论】:
CakeRequest 在任何 2.x 版本中都没有 setStatus。如果你想在 2.x 中设置状态码,你应该使用CakeResponse 的status 方法。它需要您要设置的状态码的整数版本。
response,但输入了request。
_serialize 变量对我不起作用。在使用$this->response->statusCode() 设置状态码后,我必须添加return $this->response。我正在使用 Cake 2.4.5。
在重新审视这个问题并阅读 Adriano 对我之前的回答(关于将用户重定向到友好页面)的评论后,我想出了一个新的解决方案。
在控制器中,您可以调用 $this->cakeError('error404') 来生成友好的 404 页面。这可以通过在“app/views/errors/error404.ctp”创建文件来自定义(与其他错误一样)。
在仔细查看code for cakeError 之后,我的建议是尝试通过在“app/error.php”或(可能更优选)“app/app_error.php”处创建一个文件来扩展 Cake 的 ErrorHandler。
error403(模仿error404 code)的代码如下:
class AppError extends ErrorHandler {
function error403($params) {
extract($params, EXTR_OVERWRITE);
$this->error(array(
'code' => '403',
'name' => 'Forbidden',
'message' => sprintf(__("Access was forbidden to the requested address %s on this server.", true), $url, $message)));
$this->_stop();
}
}
您应该还可以通过创建“app/views/errors/error403.ctp”来为此错误提供自定义视图。这是error404 view的修改版:
<h2><?php echo $name; ?></h2>
<p class="error">
<strong>Error: </strong>
<?php echo sprintf(__("Access was forbidden to the requested address %s on this server.", true), "<strong>'{$message}'</strong>")?>
</p>
【讨论】:
自 CakePHP 3.6 以来又发生了变化:
立即使用
$this->setResponse($this->response->withStatus(403) );
return $this->response; // use this line also
而不是
$response = $this->response->withStatus(403);
https://api.cakephp.org/3.7/class-Cake.Controller.Controller.html#_setResponse
【讨论】:
也许in this section of the cakephp manual 可以帮到你。
重定向(字符串 $url,整数 $status, 布尔值 $exit)
您将使用的流量控制方法 最常见的是redirect()。这种方法 采用形式的第一个参数 CakePHP 的相对 URL。当一个用户 已成功下单,您 可能希望将它们重定向到 收据屏幕。第二个参数 redirect() 允许你定义一个 伴随的 HTTP 状态码 重定向。您可能想使用 301 (永久移动)或 303(见 其他),取决于的性质 重定向。
该方法将在之后发出一个 exit() 除非您设置第三个重定向 参数为 false。
【讨论】:
您可以使用 cakephp response 自定义消息:
$this->response->header('HTTP/1.0 201', 'custom message');
$this->response->send();
【讨论】:
核心 PHP link 代码在 cakePHP 中工作。
header('HTTP/1.1 403 Forbidden');
【讨论】: