I have started using Yii2 basic and need to store session information. I already know that in Yii2 basic, this should be done using sessions like
$session = Yii::$app->session;
$session->open();
$_SESSION["a_id"] = $id;
$_SESSION["w_auth"] = "true";
The problem with this is that every time the browser is closed my session expire
Is there anyway to keep session alive or set session destroy so even I close the browser and open it again. It will not ask me again to put my username or password.I need to do this in the YII2 Basic .
session cookies set expire time after 7 days
`
'components' => [
'session' => [
'class' => 'yii\web\Session',
'cookieParams' => ['lifetime' => 7 * 24 *60 * 60]
],
`
You need to use cookies for this.
Cookies are info kept in your browser.
Here is how to do in yii2:
$cookies = Yii::$app->response->cookies;
// add a new cookie to the response to be sent
$cookies->add(new \yii\web\Cookie([
'name' => 'a_id',
'value' => $id,
]));
Add the above cookie when you login and then use it this way in your actions:
$cookies = Yii::$app->response->cookies;
$a_id = $cookies->getValue('a_id');
if($a_id !== null) {
// user is logged in
}
Note: What is kept in the cookie of your browser is not your actual info, but the session id and this is sent when you reopen your browser and restores your session by this id. Your actual info is kept in your session(in the server). This how yii 2 cookies work.
References
What are cookies and sessions, and how do they relate to each other?
Cookies vs. sessions
Related
Okay so I've created a login system using PHP Sessions which stores user-related data within $_SESSION while logged in. To reach a PHP $_SESSION / session cookie whose expiry gets extended by x seconds every time the client refreshes a page, I created the following callback, which I call upon every page initiation:
<?php
if ( session_status() === PHP_SESSION_NONE ) {
session_start(
[
'cookie_path' => '/',
'cookie_domain' => 'mydomain.com',
'cookie_secure' => true,
'cookie_httponly' => true,
'cookie_samesite' => 'Strict',
'use_strict_mode' => true,
'use_trans_sid' => false,
'use_only_cookies' => true
]
);
} else {
// If session already exists, simply take it up again without overwriting parameters
session_start();
}
// Then determine the lifetime of the cookie (was only able to make the session cookie
// lifetime expendable using this syntax, as explained in the [first example of the php docs](https://www.php.net/manual/de/function.session-set-cookie-params.php)
setcookie(
session_name(),
session_id(),
[
'expires' => time() + x,
'path' => '/',
'domain' => 'mydomain.com',
'secure' => true,
'httponly' => true,
'samesite' => 'Strict'
]
);
?>
The reason why I specify all the:
httponly
secure
cookie path
cookie domain
samesite
parameters upon the very first call of session_start() AND also in the call of setcookie() is because if I specify one of them in session_start() and not in setcookie() or vice-versa, the browser returns two session cookies with the same session IDs, one having all of the mentioned flags, and the other without:
Now the problem is that, when I logout via the following callback, which I call as specified in the docs:
<?php
// Called via PHP Form Submit
session_start();
setcookie(
session_name(),
'',
time() - 42000,
'/',
'mydomain.com',
true,
true
);
session_destroy();
header( 'Location: mydomain.com' );
?>
I get the same problem as described in the images above; two session cookies in my browser, and again one having all the flags set, the other not, and the one without the flags set having set its expiry to the session's end, and the other one with its expiry set in x seconds; all exactly as in the image.
What am I doing wrong?
UPDATE
Is it may better to actually set all of the session cookie parameters via the php.ini file, and handle the session cookie expiry via a timestamp within $_SESSION, done like in this example?? Just thinking of a way of making the provision of any parameters in session_start() + any calls to setcookie() obsolete..
So my question is basically:
What's actually the best way of using several PHP session cookie flags, combined with a session expiry which is limited to let's say 10 mins, which gets refreshed by 10 mins on every page load?
I have used setcookie in php to check users visiting my site. The thing is when i test it in my local server it works, the cookie gets set but when i upload the page in cpanel the cookie doesn't get set.
Below is a synopsis of my code:
<?php
session_start();
//set the cookie time to desired value;
setcookie("user", "abc", time()+3600);
//some other codes
if(!isset($_COOKIE["user"]))
{
//some other codes
}
?>
Any help will be much appreciated. Thanks
Regarding the answers to my questions in the comments, you probably just need to modify the cookie lifetime of your session and not create another "user" cookie.
// TTL (Time To Live) of the cookie stored in the browser.
ini_set('session.cookie_lifetime', 432000); // 5 days
// On the server side, the garbage collector should delete
// old sessions too, after the same TTL.
ini_set('session.gc_maxlifetime', 432000); // 5 days
// Fire the garbage collector only every 100 requests.
ini_set('session.gc_probability', 1);
ini_set('session.gc_divisor', 100);
Do that at the beginning of your code, typically in a config.php file included at the bootstrap of your app.
You can see more in the PHP session configuration.
There's a little problem regarding the lifetime: the cookie will expire after the lifetime set, but since the cookie was created, so at the moment your session was initiated the first time at login.
Usually, you want the cookie lifetime to start at the last user's action. You can do that by updating the cookie so that PHP re-sends the Cookie HTTP header to overwrite it. I also added a bunch of other security settings one should do on PHP sessions. Everything is commented in the running example below:
<?php
/**
* Testing PHP cookie settings and improve security.
*/
// The cookie lifetime in seconds.
define('COOKIE_LIFETIME', 10);
// Simulate user's data from the database.
$user_mail = 'james.bond#gmail.com';
// A salt per user is good. It avoids an attacker to be able
// to calculate the session cookie name himself if he discovers that
// it is just done by hashing the user's e-mail.
$user_salt = 'nbVzr432';
// Detect if we are over HTTPS or not. Needs improvement if behind a SSL reverse-proxy.
// It's just used for the cookie secure option to make this POC work everywhere.
$is_https = isset($_SERVER['HTTPS']) && !empty($_SERVER['HTTPS']);
// On the PHP server side, the garbage collector should delete
// old sessions after the same lifetime value.
ini_set('session.gc_maxlifetime', COOKIE_LIFETIME);
// Fire the garbage collector only every 100 requests to save CPU.
// On some OS this is done by a cron job so it could be commented.
ini_set('session.gc_probability', 1);
ini_set('session.gc_divisor', 100);
// Improve some session settings:
ini_set('session.use_cookies ', 1);
ini_set('session.use_only_cookies ', 1);
ini_set('session.use_strict_mode ', 1);
// This POC will just print some plain text.
header('Content-Type: text/plain; charset=utf-8');
// Change the session cookie name so that an attacker cannot find it.
$session_cookie_name = 'SESS_' . sha1($user_mail . $user_salt);
// Store all the session cookie options in an array.
$session_cookie_options = [
// Set the cookie lifetime (the browser sets an expire to delete it automatically).
'lifetime' => COOKIE_LIFETIME,
// The cookie path defines under which relative URL the cookie should be sent.
// If your app is running under https://your-site.com/shop/ then the cookie path
// should be set to /shop/ instead of the default / as there's no reason to send
// your shop's session cookie to another app running at https://your-site.com/forum/.
'path' => '/',
// Cookie domain. Use null to let PHP handle that. But if you want a session
// cookie accross multiple sub-domains such as forum.your-site.com and shop.your-site.com
// then you should set the domain to ".your-site.com".
'domain' => null,
// If we are in HTTPS then don't let cookies be sent over HTTP.
// Here I used $is_https to make it run everywhere but if you have
// HTTPS on your domain then replace it by 1 to lock it!
'secure' => $is_https ? 1 : 0, // IMPORTANT: Replace by 1 if you have both HTTP and HTTPS enabled.
// Don't let JavaScript access the session cookie.
'httponly' => 1,
// If another site has a link pointing to your website then don't send
// the session cookie (POST or GET). This mitigates somes kind of attacks.
'samesite' => 'Strict',
];
// Apply all the session cookie settings without ini_set() for maximum portability:
session_name($session_cookie_name);
session_set_cookie_params($session_cookie_options); // Since PHP 7.3 only
session_start();
// If the session cookie has been sent by the browser then it might have an expiration
// date to early (because it is set only once at the creation of the session).
// Instead we would like it to expire with our lifetime since the last user's
// action. To do that we have to use setcookie() to resend the cookie in order
// to update/overwrite it to have a new expiration date in the browser.
if (isset($_COOKIE[$session_cookie_name]) && $_COOKIE[$session_cookie_name] == session_id()) {
$cookie_options = $session_cookie_options;
unset($cookie_options['lifetime']); // This one is replaced by expires below.
$cookie_options['expires'] = time() + COOKIE_LIFETIME;
setcookie($session_cookie_name, session_id(), $cookie_options);
}
// Now that HTTP headers have been set, we are allowed to start printing output.
// If the user is already logged and his caddie is empty then fill it with some
// random stuff. It will stay saved until the session expires.
if (isset($_SESSION['session_creation_date']) && !isset($_SESSION['shop_caddie'])) {
$_SESSION['shop_caddie'] = [
'T-shirt' => [
'quantity' => rand(1, 3),
'color' => 'red',
],
'Beer' => [
'quantity' => (['2dl', '3dl', '5dl'])[rand(0, 2)],
]
];
}
// If the session is empty, let's init it with the creation date for the showcase.
if (empty($_SESSION)) {
$_SESSION['session_creation_date'] = date('r');
}
print 'Recieved cookies from the browser = ' . var_export($_COOKIE, true) . "\n\n";
print 'Session data = ' . var_export($_SESSION, true) . "\n\n";
In my Cakephp application, i have a session cookie with the name 'my_cookie' and it contains some random value 'QSD5111AS552DNJK'.
I observed that the value is same for the cookie (Before login and After login also). If i want to change the cookie value after login, what are the steps i have to follow.
And my code in core.php file
Configure::write('Session', array(
'defaults' => 'php',
'cookie' => 'my_cookie',
'timeout' => 4000
));
Please help me in this issue for getting more clarification.
I guess what you want to do is prevent session fixation, in that case it should be noted that CakePHP already does this for you out of the box. When using the authentication component, the session is being renewed before the authenticated user data is being written to it, and after the user data is being deleted on logout.
See
Source > AuthComponent::login()
Source > AuthComponent::logout()
For the sake of completeness, you can always renew the session manually, either via the session component in case you are in a controller
$this->Session->renew();
or by using the CakeSession class directly
App::uses('CakeSession', 'Model/Datasource');
CakeSession::renew();
I am trying to increase the session lifetime in cakephp app. I have a remember me checkbox in login page. When checking the checkbox, I need to extend session time to 1 hour more to current time and any action inside the app after login will need to extend session time to 1 hour more.
I have component file for login and all action will be entered in startup function.
I tried to extend the session.cookie(CakePHP's session cookie) lifetime, but it didn't works.
function startup(&$controller) {
/* First try */
setcookie(Configure::read('Session.cookie'),$_COOKIE[Configure::read('Session.cookie')], time() + 3600, "/"); // Configure::read('Session.cookie') is 'CAKEPHP'.
/* Second try */
ini_set('session.gc_maxlifetime', 3600);
/* Third try */
session_set_cookie_params(time() + 3600);
echo $this->Session->read('status').' session <br/>';
echo $_SESSION['test'];
}
But all of these doesn't keep the session after session.timeout(CakePHP's session timeout) time. The session status and test varaibles are created on login. It will be retrieved until session.timeout is not reached.
I am using cakephp v1.2.
keep this in your core.php file
Configure::write('Session', array(
'defaults' => 'cake',
'timeout' => 14400, // 4 hours
'cookieTimeout' => 14400, // 4 hours
'cookie' => 'Your Cookie Name',
)
);
It is not a good idea to keep very high session timeout. If your requirement is only to keep him logged for more time, then use some auto_login component like www.milesj.me/resources/script/auto-login
I have set cookie and set it to expire after sufficient seconds. Still as soon as my session expires the cookie also expires. This is my code :-
if(isset($_POST['KeepMesignedIn'])) {
$this->load->helper('cookie');
$cookie = array(
'name' => 'info',
'value' => $user->Username . '||' . $user->Password,
'expire' => time()+3600*24*30
);
set_cookie($cookie);
}
Can anybody identify the problem?
According to the CodeIgniter documentation, set_cookie expects expires to be the delta seconds that are added to the current time:
The expiration is set in seconds, which will be added to the current time. Do not include the time, but rather only the number of seconds from now that you wish the cookie to be valid. If the expiration is set to zero the cookie will only last as long as the browser is open.
check is this part of code executed in your app or not. You need to debug.