Using CakePHP 2.1
I have the following code
public function getForm($id=null){
$this->loadModel('DynamicFormResponse');
/**
* Check if form exists
*/
$this->form_schema= $this->DynamicForm->isValidForm($id);
if($this->form_schema == false){
$this->flash("Invalid form", $this->referer(
array('controller'=>"pages", 'action' => 'display')
));
}
...
...
the problem I am facing is that, the call to $this->flash()
renders the flash page but also continues the execution of the controller.
So Unless I do something like
if($this->form_schema == false){
$this->flash("Invalid form", $this->referer(
array('controller'=>"pages", 'action' => 'display')
));
return;
}
the controller does not terminate .
The main problem arises when a _crsf_error
method is called
function _csrf_error() {
$this->flash("csrf Error", $this->referer(
array('controller'=>"pages", 'action' => 'display')
));
}
Since the flash method does not redirect It offers no csrf protection at all. Using return;
after $this->flash()
in the _crsf_error
method does not work.
PS: Full code available here
flash()
does not redirect, it renders. It is very similar to the render()
function, it will continue the execution of the script, unlike the redirect()
function.
You just need to organize your logic accordingly, so that no other line is executed after it If you don't want to. Optionally you can use session->setFlash()
combined with a redirect.
When dealing with serious errors like an invalid csrf token I'd recommend throwing an exception instead of rendering a nice message to the attacker. You can prettify the exception rendering using the error handler, though.
Although the answer above is a great explanation of what the flash() method does, to me, it did not fully answer the question but rather give a great alternative.
I personally wanted to use the flash method so I didn't have to use the session component and I found myself stuck on my flash message as well. In the cake 2.x documentation, it says that the second parameter of the flash() method is a CakePHP-relative URL. This means the following should show a message and then redirect to the index action.
$this->flash(__("Some message for the user here..."), array("action" => "index"));
My problem, and what it looks like the original poster's problem, was that it was showing you the flash message but not doing the redirect after.
I tested this thoroughly with my application and the culprit was the debug setting in core.php
Configure::write('debug', 0);
The debug value has to be set to '0' in order for the redirect to take place. I do not know why this is the case but I tested it about 10 times and 10/10 when my debug settings were set to 1 or higher, I just got the flash message. If I set it to 0, everything works perfectly. This wasn't much of a concern to me since production environments should have this setting set to 0 anyway.
If anyone else has some insight as to why the redirect doesn't happen when debugging is on, please enlighten us all.
Hope this helps.
I was also facing the same problem. And after turning debug mode to 0,i got the solution of my problem.
Configure::write('debug', 0);
And why redirect was not happening with debug mode 2 there is one main cause,
your application is outputting something to the browser before the redirect header was sent. This may be caused by (non visible) white-space before or after any . This will cause a 'headers already sent' warning, and the browser will not redirect. There are many questions regarding this situation here on StackOverflow, for example: Headers already sent by PHP