In my controller, I check a condition to see if the user is allowed to do something. If the check fails, I want to send a 403 back to the browser. How do I do that in Cakephp?
-
1It is also worth noting that CakePHP 3x is [PSR-7](https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-7-http-message.md) compliant. – jtrumbull Jul 03 '17 at 17:51
10 Answers
EDIT - This question is quite old and covers different versions of the CakePHP framework. Following is a summary of which version each answer applies to. Don't forget to vote on the solution that helps most.
- CakePHP 3.x and 4.x - using response object (Roberto's answer)
- CakePHP 2.x - using exceptions (Brad Koch's answer) [preferred solution]
- CakePHP 2.x - setting header only (Asa Ayers' answer)
- CakePHP 1.x - using error handler (my other answer)
- CakePHP 1.x - setting header only (this answer)
EDIT #2 - A more detailed answer for CakePHP 2.x has been added by Mark37.
EDIT #3 - Added solution for CakePHP. (May 2018: CakePHP 3.5 did some function renaming, solution by Roberto is still valid.)
By looking at the relevant API code from the previous comment, it seems you can call Controller::header($status) to output a header without redirection. In your case, the proper usage is most likely:
$this->header('HTTP/1.1 403 Forbidden');
-
Also, the code above only outputs the header, so you may want to end execution with `return false`, `die`, `exit`, or something similar. – deizel. Jul 08 '09 at 23:37
-
This answers the question more precisely than my answer. Still, I think it's useful to be able to redirect the user to a custom page in this case, it's nicer than a blank 'the server responded this' page. – Adriano Varoli Piazza Jul 10 '09 at 12:40
-
Looking at the body of that method, it seems to be a wrapper around a built in function called header. – allyourcode Jul 10 '09 at 22:26
-
since all of cakephp is actually more php, indeed most stuff could be boiled to 'a wrapper around a built-in function'. The idea is that your development is eased by the wrapping, and that the performance overhead is negligible. – Adriano Varoli Piazza Jul 11 '09 at 15:22
-
What I mean is, header() is the standard way to send an http header in PHP, but you did ask 'How do I do this using CakePHP', which, I assume, implies 'I'm going to use what Cake offers'. – Adriano Varoli Piazza Jul 15 '09 at 18:05
-
Since $this->header in a controller is exactly like the PHP std `header` function, I prefer to use the latter. When a method does NOT provide a higher level of abstraction, it's a distraction and should be avoided. On the other hand, other parts of CakePHP do provide higher levels of abstraction. I'll continue to use such parts to make my code more understandable, and my life easier.. – allyourcode Mar 14 '10 at 00:32
-
This isn't a good solution as the implementation of `$this->header` expects everything to have something split with a colon. See my answer below for more details. – Asa Ayers Jul 13 '12 at 16:50
-
According to [this](http://php.net/manual/en/function.header.php#92305) it's better to write `$this->header($_SERVER['SERVER_PROTOCOL'] . ' 403 Forbidden');` – Till Jul 25 '17 at 08:27
Notes concerning CakePHP 3.x seem to be missing, so to make this thread complete:
For CakePHP 3.x and 4.x use:
$response = $this->response->withStatus(403);
return $response;
For versions before CakePHP 3.3.x you can use the same style as CakePHP 2.x:
$this->response->statusCode('code');
Note that using the PHP function directly also works (http_response_code(403); die();
), though using the response object seems like the intended method.

- 958
- 13
- 33
-
1```return $this->response->withStatus(403);``` also applies to CakePHP 4.x: https://api.cakephp.org/4.1/class-Cake.Http.Response.html#withStatus – danialk Dec 03 '20 at 08:07
-
any idea to send 403 and json data? I was using $this->response->statusCode('403'); and $this->set(compact('data')); $this->set('_serialize', ['data']); And it was working very well until I updated to v 3.9 – Kelvin Primo Aug 06 '21 at 15:57
-
You could try forcing a view or template. Maybe the `ErrorController` kicks in when you return an error status. – Roberto Aug 06 '21 at 19:17
$this->response->statusCode(403);
Will set the status code when Cake is ready to send the response. CakeResponse::send() expects to send the status code and message, so in my tests I think my using header()
was getting overwritten. using $this->header('HTTP/1.1 400 Bad Request')
doesn't work either because Cake expects any call to $this->header
to be split on a colon ex: $this->header('Location: ...')

- 4,854
- 6
- 40
- 57
-
2+1 for a CakePHP 2.x answer (`$this->response->...`) which may help current visitors from Google, etc. (For those visitors: the answers dated 2009 are for the CakePHP 1.x codebase) – deizel. Jul 16 '12 at 14:09
-
This will work, but Exceptions tend to be preferred for these types of situations in CakePHP 2. They abort controller execution immediately, and they trigger cake's standard error handling process. – Brad Koch Oct 05 '12 at 13:27
-
3Exceptions are better for 4xx and 5xx statuses, but if you need to (for example) return 201 to a POST request, this might be the way to go. – eaj Jan 23 '13 at 20:51
In CakePHP 2, the preferred method is to throw an exception:
throw new ForbiddenException();

- 19,267
- 19
- 110
- 137
-
it is working for `cakephp 3.6` but this code not using the `error403.ctp` template. How to set the `error403.ctp` template fro `ForbiddenException()` – Er. Amit Joshi Feb 01 '19 at 10:09
I'm adding in my two cents here because I don't feel like any of these answers covered this topic as thoroughly as I would have liked (at least for Cake 2.x).
If you want to throw an error status, use the Exception classes (as mentioned in other answers):
throw new BadRequestException(); // 400 Bad Request
// Or customize the code...
throw new BadRequestException('Custom error message', 405); // 405 Method Not Allowed
Fun fact: Cake will automatically do some magical error rendering even for RESTful calls via the ExceptionRenderer
class. Even more fun of a fact is that it's based on the Status Code, not the fact that an Exception
might have been thrown, so if you set the status code to > 400 on your own you will likely get error messages even if you didn't want them.
If you want to return a specific status code for a REST JSON/XML endpoint, take advantage of the new CakeResponse
object, but also make sure that you add the special _serialize
variable or you'll end up with a 'view not found' error as cake will attempt to find a view to render your JSON/XML. (This is by design - see the JsonView
/XmlView
class.)
$this->response->setStatus(201); // 201 Created
$this->set('_serialize', array()); // Value must be something other than null
And lastly, if you want to send a non-200 status for a regularly rendered page, you can just use the setStatus()
method with nothing else as mentioned in a previous answer:
$this->response->setStatus(201);
UPDATE:
$this->response->setStatus('code');
is no longer available. Use
$this->response->statusCode('code');
-
1
-
`CakeRequest` doesn't have `setStatus` in any of the 2.x releases. If you want to set status codes in 2.x you should use `CakeResponse`'s `status` method. It takes an integer version of the status code you want to set. – Blake Hair Jul 24 '14 at 13:56
-
Thanks @BlakeHair - I think when I wrote this originally I meant to write `response` but typed `request` instead. – Mark G. Jul 24 '14 at 16:06
-
Using the `_serialize` variable didn't work for me. I had to add `return $this->response` after setting the status code with `$this->response->statusCode()`. I'm using Cake 2.4.5. – Elliot Vargas Jan 13 '15 at 14:56
Upon revisiting this question, and reading Adriano's comment on my previous answer (regarding redirecting the user to a friendly page), I have come up with a new solution.
Within a controller you can call $this->cakeError('error404')
to generate a friendly 404 page. This can can be customised (as with other errors) by creating file at 'app/views/errors/error404.ctp
'.
After having a closer look at the code for cakeError
, my recommendation is to try extending Cake's ErrorHandler
by creating a file at 'app/error.php
' or (possibly more preferable) 'app/app_error.php
'.
The code for your error403
(mimicking the error404
code) could read as follows:
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();
}
}
You should also be able to provide a custom view for this error by creating 'app/views/errors/error403.ctp
'. Here is a modified version of the 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>

- 11,042
- 1
- 39
- 50
-
Good answer! This is one thing I didn't know you could do with Cake. – Adriano Varoli Piazza Aug 02 '09 at 12:11
It has changed again since CakePHP 3.6:
Use now
$this->setResponse($this->response->withStatus(403) );
return $this->response; // use this line also
instead of
$response = $this->response->withStatus(403);
https://api.cakephp.org/3.7/class-Cake.Controller.Controller.html#_setResponse
-
Interestingly that method isn't demonstrated outside the API at all. There is no mention of it in https://book.cakephp.org/4/en/controllers/request-response.html I'm not sure what the method does additionally. – Roberto Feb 16 '21 at 07:53
Perhaps something in this section of the cakephp manual can help you.
redirect(string $url, integer $status, boolean $exit)
The flow control method you’ll use most often is redirect(). This method takes its first parameter in the form of a CakePHP-relative URL. When a user has successfully placed an order, you might wish to redirect them to a receipt screen. The second parameter of redirect() allows you to define an HTTP status code to accompany the redirect. You may want to use 301 (moved permanently) or 303 (see other), depending on the nature of the redirect.
The method will issue an exit() after the redirect unless you set the third parameter to false.

- 7,297
- 5
- 39
- 50
-
But I don't want to send a 3xx status code back. Even if this works, it seems wrong. – allyourcode Jul 08 '09 at 23:24
-
1You can send any status code back, the 303 are just an example. – Adriano Varoli Piazza Jul 08 '09 at 23:30
-
This is perfect for 3xx redirect status codes. Definitely a horrible idea for everything else, like the user's 403. – Brad Koch Mar 13 '13 at 04:27
You can use cakephp response
for custom message:
$this->response->header('HTTP/1.0 201', 'custom message');
$this->response->send();

- 191
- 1
- 6
Core PHP link code works in cakePHP.
header('HTTP/1.1 403 Forbidden');

- 1,114
- 17
- 26