Setting cookies not working in CodeIgniter - codeigniter

I wnat to set cookie with a name csrf_cookie_name with a value from this function $this->security->get_csrf_hash(); but, it is not working.
I have this in my controller:
$csrf_cookie_value = $this->security->get_csrf_hash();
$this->input->set_cookie('csrf_cookie_name', $csrf_cookie_value);
echo $this->input->cookie('csrf_cookie_name');
die();
But it is not working and nothing is echoed out.
If I try only this:
$csrf_cookie_value = $this->security->get_csrf_hash();
echo $csrf_cookie_value;
I works and a generated string is echoed out.
So, I assume that something within these next 2 lines is wrong:
$this->input->set_cookie('csrf_cookie_name', $csrf_cookie_value);
echo $this->input->cookie('csrf_cookie_name');
Thanks for your advice.

You need to specify a life time for the cookie. 0 will be a session cookie and anything else will be added to time().
If you don't specify a life time, CI will interpret that you want to delete the cookie. And that's exactly what it does :)
$this->input->set_cookie('name', 'value', 0); //expires when the browser window closes
$this->input->set_cookie('name', 'value', 3600); //expires in one hour
$this->input->set_cookie('name', 'value'); //will delete the cookie (if the cookie does not exist, you will not notice anything happening)

The reason you are not getting a cookie echoed is because the $this->input->cookie() function reads directly from the global $_COOKIE array and $this->input->set_cookie() does not populate the $_COOKIE array immediately on the server. Instead, $this->input->set_cookie() queues the cookie to be sent back and stored in the browser. Only on the users' next HTTP request will you be able to re-observe this cookie.
Secondly, and perhaps more importantly, is that I think you are using the csrf cookie improperly. To protect against cross site request forgery only requires you to enable it and set it's properties in config/config.php. That is it. There is no need to read and write it in the controllers at all.

The cookie is already there. You can consult via Javascript with:
$.cookie("<?php echo $this->config->item("csrf_cookie_name"); ?>");
I hope be useful.

Related

Laravel: How to mark Session data as flashed

I am trying to pre-populate an input on a form for the creation of a model entity in Laravel 5.4. But the form is a shared blade template with the edit form for the same model, where I want to use form-model binding to provide the input.
The way I have achieved this so far is to flash a session variable to _old_input in the controller for the creation route:
session()->flash('_old_input.description', $event->description);
This achieves exactly what I want it to, with the exception of not being cleaned out at the end of the request. My next request still has the session data flashed.
My question is how does Laravel know that this is the recipient of a flash message as opposed to the input of a flashed message? And is there a way to tell it that I've already used the session flash and it should be cleaned up at the end of this request...
You need to use redirect to flash the session... otherwise, you will end up with the flash staying on for the next request...
You can return a view... like
return redirect('view')->with('_old_input.description', $event->description);
Or you can even redirect to a controller action ... like
session()->flash('_old_input.description', $event->description);
return redirect()->action('MyController#function');
which would work also... the key is to return a redirect response...
Hope this helps...
Serge is correct that flash is intended for use to put data into the session for the NEXT request and thus redirecting is the correct way to do this, I will also provide here the solution I used to hack my way past this...
Laravel stores its flash data in the _flash value in the session array, with keys which are to be used in the NEXT request under the new key, and keys which were used in THIS request in the old key; see extract below.
[_flash] => Array
(
[old] => Array
(
)
[new] => Array
(
[0] => _old_input
)
)
Using session()->push('_flash.old', '_old_input'); fools Laravel into thinking that this is data that was flashed into this request from the previous one, and clears up the data at the end of its cycle.
For full effect, you can use session()->forget('_flash.new.0'); to remove it from the new key, although beware that this is not necessarily the first flashed var (in my case it is).
My total code is therefore:
session()->flash('_old_input', ['description' => $event->description]);
session()->push('_flash.old', '_old_input');
session()->forget('_flash.new.0');
Again, Serge is correct but if anyone else comes here to find out how Laravel's flashing works and wants to circumvent it, here is a bit of information

Laravel and redirect->back or something?

I need someway to redirect my app to a previous url.
The problem comes when i make a submit that goes wrong, the redirect->back previous url is someway "overwrited" and i cannot get the previous real url anymore, instead the app makes the submit again.
The only thing that i tried is the redirect back, because i can't find another way to do it :S
So i´m wondering if there is a way to achieve that, redirect the app to a previous url without considering the submit fails and all this stuff.
Thank you.
Yo can try with:
return Redirect::to(URL::previous());
You can store URLs in session and then make Laravel redirect 2 or 3 pages back. Simple example of code to store URL in session:
$links = session->has('links') ? session('links') : []; // Get data from session
array_unshift($links, $_SERVER['REQUEST_URI']); // Add current URI to an array
session(compact('links')); // Save an array to session
And example of code for redirecting:
return redirect(session('links')[2]);

JQuery Cookie plugin - check for presence of cookie

I hope this is a simple question, but can't find it covered elsewhere.
I simply want check for the presence of a cookie - if it's there, do nothing, but if it's not there, replace the content of a particular div (I think I know how to do this last bit.
Any ideas?
you can check cookie existence at server side before rendering page. you will get all cookie details in request object If your cookie not there,then replace the content of a particular div in server side
otherwise you can check in client side as below, if (jQuery.cookie('cookietitle')) {
// Reactions
}
You may read it like var cookieValue = $.cookie("test"); And check the cookieValue if is empty.
Check this answer for more details how to work with cookies:
How do I set/unset cookie with jQuery?

Twilio Session Variable in Number action url

I'm setting up a whisper function in my call plan and can't seem to pull a session variable on the 'url' in the action. Are session variables supported there?
I have this in my dial action:
<Number url="whisper.php">15551234567</Number>';
And my whisper.php looks like this.
<?php
session_start();
header('Content-type: text/xml');
echo '<Response>';
echo '<Say>Call from '.$_SESSION['source'].'</Say>';
echo '</Response>';
?>
$_SESSION['source'] isn't showing up.
I use this session variable elsewhere and store things in a database with it so I know it is set correctly.
I went to Twilio support and they gave me this info in case someone else ever looks at this.
"Twilio's cookie handling is keyed by the combination of From and To. For the <Number url> request, the From and To will be different than the From and To of the parent call, so that's probably why the 2 sessions aren't being shared and you get a new session."
The the URL action is not in the same session.
He gave me this as a work around:
"The most common workaround is to include the extra data as a query parameter, e.g.
<Number url="whisper.php?source=<?= $_SESSION['source'] ?>">15551234567</Number>
It's not very elegant but it works well enough for maintaining state during the call flow.
And then in whisper.php you would access $_REQUEST['source'] instead of $_SESSION['source']."
Each seperate number to number pair holds a separate Session and cookie jar as if the twilio "browser" is browsing a different site. Therefore, passing it into the url above is the only way to post the value across the two different pairs of numbers.

Action you have requested is not allowed error

I made a module named Gallery which works fine on my localhost with version 2.0.3, but when using version 2.1.0 on a remote site I can not submit a form and I get the error:
The action you have requested is not allowed.
Why is this?
I agree with #Jhourlad Estrella on fixing the problems instead of disabling a security feature, however I feel that the real problem is with the hidden input field that holds the token.
Instead of using plain HTML to create a form element use the the form_open() and form_close() helper functions. The reason why is because when you use the helper function it automatically inserts the csrf token as a hidden field in the form.
You could do this manually as well by adding the token as a hidden input field in the form
<input type="hidden" name="csrf_hash_name" value="your-hash-value-here">
Doing it this way will allow you to stay protected from CSRF attacks and fix the problem you are having.
Hope this helps someone else out there as this was driving me nuts the first time figuring this out.
It is a Codeigniter error related to the CSRF protection. You can cancel it in cms/config/config.php
On matters of programming, you don't go around problems, you fix it. What I mean to say is, this feature won't be here if it is unusable: 'coz it is and it works for me. You just have a problem on the implementation.
My answer: Remove all dashes, periods and any other non-alphanumeric characters from the values of following entries on application/config/config.php as seen below:
$config['sess_cookie_name'] = 'mycookiename'; //instead of "my_cookie_name"
$config['csrf_token_name'] = 'mycsrftoken'; //instead of "my.csrf.token"
$config['csrf_cookie_name'] = 'mycsrfcookie'; //instead of "my/csrf/cookie"
BTW, dashes sometimes work but I suggest using single words whenever possible when naming config values. Not unless you have the time and skills to study Codeigniter's core files related to what ever you are working on just to make sure it's safe to do so.
Anyways, I hope this help somebody out there even though my answer is more than a year late.
I have a form that was built outside of CI (in Joomla), but that I wanted to process with CI. My fix was to selectively disable csrf for specific referrers. I added this to config, directly after the default config options for csrf:
/* Set csrf off for specific referrers */
$csrf_off = array(
"http://yourdomain.com/your-form-url",
"http://yourdomain.com/some-other-url"
);
if (isset($_SERVER["HTTP_REFERER"])) {
if (in_array($_SERVER["HTTP_REFERER"],$csrf_off)) {
$config['csrf_protection'] = false;
}
}
This disables csrf protection for specific URLs in the $csrf_off array, but leaves it intact for all other requests.
I have found using the form helper functions
Example
<?php echo form_open('controller/function');?>
<?php echo form_input('username', 'Username');?>
<?php echo form_close();?>
Using the helper functions like above should stop the CSRF error message showing.
If I don't use echo form_input() if I place just normal input will trigger the CSRF error when reload.
<?php echo form_open('controller/function');?>
<input type="text" name="username" />
<?php echo form_close();?>
So I recommend using all form helper functions now.
It is an old question but this same problem did cost me so much time that I wanted to share what the problem was in my case. It may help someone.
I am using Codeigniter 3.0.6 and CommunityAuth 3 together with it and I was getting this error after a login.
It was confusing since the problem would sometimes happen and would not other times.
My 'base_url' in CI's config.php was set to something like 'www.mysite.com'
When you browse the site with 'mysite.com' (notice 'www' is not in the address) and you do a form submission that uses CI's 'base_url' setting, like CommunityAuth's login does, then CSRF check fails and you get 'The action you have requested is not allowed.' error.
This error is thrown by the function csrf_show_error() in system/core/Security.php when the CSRF token in $_COOKIE doesn't match your $_POST['csrf_token_name'].
Inside config.php, I had to ensure that $config['cookie_domain'] matched $config['base_url'], without the protocol (i.e. http(s)://).
Otherwise, the cookie wasn't being passed which meant the match couldn't be made.
Use the codeigniter form opener like this:
<php echo form_open(url,method,attributes);?>
see codeigniter form documentation for more.
This is probably a rare case, but I didn't see my issue since my server has many different domain names that are very similar. The problem was that I was landing on a domain that was completely wrong, but since "The action you have requested is not allowed." error takes precedence over " 404 Not Found Error" I couldn't see it. My problem was that I didn't change my base_url to the correct domain. So if none of the above solutions work for you, you might check your settings for $config['base_url'] in application/config.
For me the problem was that I was loading the view in the index, than I changed as follow and it worked:
public function index()
{
// Load Login Page
redirect('login/login_page','refresh');
}
public function login_page()
{
$data['title'] = 'Login Page';
$this->load->view('templates/header', $data);
$this->load->view('users/login_view', $data);
$this->load->view('templates/footer');
}
Im Using Codeigniter 3 same problem with
The action you have requested is not allowed.
Based on Isaac Pak's point, i changed my base_url to what i usally typed at the address bar. like this...
instead of putting
http://www.domain.org
i write it this way..
http://domain.org
since my base_url() is just..
$config['base_url'] = 'http://domain.org/';
the fix works for my site...

Resources