I'm working on a large-scale web app in Codeigniter with HMVC modular extensions and having problems with sessions whilst using the database (to store the sessions).
My sessions are being lost for a reason I can simply not understand.
A prime example is using the Codeigniter cart. I can successfully add items to my cart and click around the site with the items remaining in the session. However, when clicking around/pause navigating the website for ~ 3 minutes (not timed to the second) the cart losses all it's products and the session is empty. When reviewing the database, the old session is still stored in the database with the content but with a new session row created (as below).
I'm running the latest version of Codeigniter with no extensions to the original Session.php class.
Below are my session config variables:
/*
|--------------------------------------------------------------------------
| Session Variables
|--------------------------------------------------------------------------
|
| 'sess_cookie_name' = the name you want for the cookie
| 'sess_expiration' = the number of SECONDS you want the session to last.
| by default sessions last 7200 seconds (two hours). Set to zero for no expiration.
| 'sess_expire_on_close' = Whether to cause the session to expire automatically
| when the browser window is closed
| 'sess_encrypt_cookie' = Whether to encrypt the cookie
| 'sess_use_database' = Whether to save the session data to a database
| 'sess_table_name' = The name of the session database table
| 'sess_match_ip' = Whether to match the user's IP address when reading the session data
| 'sess_match_useragent' = Whether to match the User Agent when reading the session data
| 'sess_time_to_update' = how many seconds between CI refreshing Session Information
|
*/
$config['sess_cookie_name'] = 'myhmvc_session';
$config['sess_expiration'] = 7200;
$config['sess_expire_on_close'] = FALSE;
$config['sess_encrypt_cookie'] = FALSE;
$config['sess_use_database'] = TRUE;
$config['sess_table_name'] = 'users_sessions';
$config['sess_match_ip'] = TRUE;
$config['sess_match_useragent'] = TRUE;
$config['sess_time_to_update'] = 300;
/*
|--------------------------------------------------------------------------
| Cookie Related Variables
|--------------------------------------------------------------------------
|
| 'cookie_prefix' = Set a prefix if you need to avoid collisions
| 'cookie_domain' = Set to .your-domain.com for site-wide cookies
| 'cookie_path' = Typically will be a forward slash
| 'cookie_secure' = Cookies will only be set if a secure HTTPS connection exists.
|
*/
$config['cookie_prefix'] = "my";
$config['cookie_domain'] = "myhmvc.co.uk";
$config['cookie_path'] = "/";
$config['cookie_secure'] = FALSE;
Any help is greatly appreciated, willing to try anything at this stage.
I've still not gotten round to understanding Codeigniter's issue with sessions but from reading other posts there's quite an issue with default sessions.
I've installed the Session Driver seen here:
http://getsparks.org/packages/session-driver/versions/HEAD/show
Which has now fixed the issue.
I hope this helps others who have had similar problems.
Related
My session is always destroyed after refreshing the page.
This is my setting.
app.sessionDriver = 'CodeIgniter\Session\Handlers\DatabaseHandler'
app.sessionCookieName = 'sippeg_session'
app.sessionExpiration = 0
app.sessionSavePath = 'ci_sessions'
app.sessionMatchIP = false
app.sessionTimeToUpdate = 300
app.sessionRegenerateDestroy = false
I don't have any code that leads to session_destroyed.
My session is still available before the redirect:
But when I refresh the page, the session has gone:
Explanation:
CodeIgniter 4 Session Preferences
If sessionExpiration is set to 0, the session.gc_maxlifetime setting
set by PHP in session management will be used as-is (often the default
value of 1440). This needs to be changed in php.ini or via ini_set()
as needed.
Excerpt From The php.ini file (session.cookie_lifetime)
; Lifetime in seconds of cookie or, if 0, until browser is restarted.
; https://php.net/session.cookie-lifetime
session.cookie_lifetime = 0
Excerpt From The php.ini file (session.gc-maxlifetime)
; After this number of seconds, stored data will be seen as 'garbage' and
; cleaned up by the garbage collection process.
; https://php.net/session.gc-maxlifetime
session.gc_maxlifetime = 1440
; NOTE: If you are using the subdirectory option for storing session files
; (see session.save_path above), then garbage collection does *not*
; happen automatically. You will need to do your own garbage
; collection through a shell script, cron entry, or some other method.
; For example, the following script is the equivalent of setting
; session.gc_maxlifetime to 1440 (1440 seconds = 24 minutes):
; find /path/to/sessions -cmin +24 -type f | xargs rm
Solution:
Based on the fact that you normally don't have access to the php.ini file on shared web hosting services to configure the session.gc_maxlifetime, it would be more convenient to set that directly in the .env file at the root path of your project. I.e:
Instead of:
app.sessionExpiration = 0 ❌
Use this:
The time is measured in seconds. 86400 = 24 hours.
app.sessionExpiration = 86400 ✅
cookie.expires = 86400
I've just caught a crash reported on sentry, I am trying to debug and see the root cause for the problem.
Luckily, in the cookies panel, I can see the laravel_session value that was used while crash happened.
The question, is, how can decrypt the cookie?
You can decrypt the cookie with the following code:
$cookie = 'eyJpdiI6ImFUQ0FvMWFSVlNvTmhlQjdLWGw1Z1E9PSIsInZhbHVlIjoicFh6Q09iTDl0K0huWU1Nc1NYVmxSY2hPRGU5Vk85dDJyYUpRbUVjRWg5R0JxYkVobkF3YkZVcVQrakFFUmxaVnZrTjFST3F3RTZ4akpDZEpvUFJiQXc9PSIsIm1hYyI6IjlhYmJhMTY3MWMxYWI3YjJmNmFjMmNkZWE0MWZmMmVhNTNiMjI5ZWY3NzUwNzQ0ZjAzMGQ1ZGU0YzVhNjJmZGYifQ==';
$cookie_contents = json_decode( base64_decode( $cookie, true ));
$value = base64_decode( $cookie_contents->value );
$iv = base64_decode( $cookie_contents->iv );
$clear = unserialize( \openssl_decrypt($value, \Config::get( 'app.cipher' ), \Config::get( 'app.key' ), OPENSSL_RAW_DATA, $iv));
echo "Cookie contents (Session ID): $clear\n";
You should end up with a session ID that looks something like this:
Laravel 5.1: 55782b00dbfcc3f848585ac2cefc66802d773cf5
Laravel 5.4: yPjeV74joY4MtMNNtTpeOYBP2CMixJBBChc9HRND
I didn't test with Laravel 5.3, but I'm confident it will work.
When using this code, make sure you paste the entire contents of the cookie into the $cookie variable, including the two equals signs at the end.
For laravel 6 I think it's pretty much the same
$base64_key = "base64:ISAcSPwQ0HDqqLygaS9LyPzs5ZujMAKOjBou+gyz9sw=";
$payload = json_decode(base64_decode($_COOKIE["your_cookie_name"]), true);
$iv = base64_decode($payload['iv']);
$key = base64_decode(substr($base64_key, 7));
$sessionId = openssl_decrypt($payload['value'], 'AES-256-CBC', $key, 0, $iv);
echo "Session Id: $sessionId";
But check few things:
Cipher encoding, mine is 'AES-256-CBC', it can be 'AES-128-CBC' if your key length is 16
Key format, mine start with "base64:" so I have to remove this part first
I am using Sentry on laravel 4.2 in one application with muti-subdomain (every domain have different users) : i want to login from one subdomain(domain-a.maindomain.com) to another subdomain(domain-b.maindomain.com) without persisting session across subdomain.
Any one have idea how can i achieve this with laravel
i think Since the Laravel authentication system uses cookies to manage the session, you actually need to login the user on each subdomain you're going to use. To avoid that, you can use another session driver like database. and what #SUB-HDR give you in his comment is a good way too do it.
I'm not familiar with Laravel before version 5.1 but there is part of the documentation which relates to authentication:
https://laravel.com/docs/4.2/security
$user = User::find(1);
Auth::login($user);
With this you may be able to authenticate a user from one of your domains to the other. You would need to pass something from the first domain to the second domain which is a unique common attribute between the two user models and then authenticate the matching user.
in (php / mysql) we can made a row called IslogedIn(or something else you prefer) in All your Databases so they''ll look like :
//---------------------------------------------
// (main database) --> site1.com
// ------------------------------------------
// | id | username | password | IslogedIn |
// |-----|-----------|----------|-------------|
// | 1 | jhony | pass | 0 |
// |-----|-----------|----------|-------------|
//---------------------------------------------
// (2nd database) --> site2.com
// ------------------------------------------
// | id | username | password | IslogedIn |
// |-----|-----------|----------|-------------|
// | 1 | jhony | pass | 1 |
// |-----|-----------|----------|-------------|
here for example we see the user is logged in 2nd database
so the value will be : IslogedIn = 1
and we gonna use that in all our domains and from "login.php" (in Laravel it can be somthing else) , from "login.php" we mark IslogedIn = 1 if the user logged in by using some mysql orders .
after that we connect all databases using a scrip page and name it something like : 'checkout.php' in both domains folders and write in it :
1 - for old php versions :
$Db_Main_con = mysql_connect($hostname, $username, $password );
$Db_2nd_con = mysql_connect($hostname, $username, $password , true);
//-------------------------------------------------------------
$Db_Main_Select = mysql_select_db("Database_name1", $Db_Main_con);
$Db_2nd_Select = mysql_select_db("Database_name2", $Db_2nd_con );
//-------------------------------------------------------------
$Db_main = mysql_query("select * from users where id = :id", $Db_Main_Select);
$Db_2nd = mysql_query("select * from users where id = :id", $Db_2nd_Select);
2 - for new version is Generally similar only some changes in the past code , such as mysql to mysqli . read this article : mysqli_connect
and I'm not familiar with Laravel so ofc you change the "$host_main_name" and "$username" and ( table name )..... etc to feet your script
and from every db call the row : (IslogedIn) in a $string.
then we go to check if the user is Logedin in all Db we have :
if ( $Db_Main->IslogedIn || $Db_2nd->IslogedIn )
{
// ----->> your login code or relogin code here
// + sessions and cookies and reloud link and all other stuff
}
then we close the script with $Db_Main->close(); $Db_2nd->close(); .... etc when the checkout is end .
I'm using:
date("d-m-Y h:i:s")
in my controller, but the time is later than actual time.
For example, now in my country it's 01:02, date return 20-06-2015 01:06:38.
How to fix it?
1st Step :
Go to config/config.php and write
//specify your region
date_default_timezone_set('Europe/Warsaw');
2nd step: now you can use your time
date("d-m-Y h:i:s") //for 21/12/2010 20:12:00
date("h:i:s") //for 12:12:11 time only
Place timezone on the top of the config.php file above base_url
date_default_timezone_set('Europe/Warsaw');
Then refresh server
<?php
defined('BASEPATH') OR exit('No direct script access allowed');
date_default_timezone_set('Europe/Warsaw');
/*
|--------------------------------------------------------------------------
| Base Site URL
|--------------------------------------------------------------------------
|
| URL to your CodeIgniter root. Typically this will be your base URL,
| WITH a trailing slash:
|
| http://example.com/
|
| If this is not set then CodeIgniter will try guess the protocol, domain
| and path to your installation. However, you should always configure this
| explicitly and never rely on auto-guessing, especially in production
| environments.
|
*/
$config['base_url'] = 'http://localhost/project/';
If you can change the hooks settings in your config file from TRUE to FALSE that should help with your issue.
Except if you have a very important need for the hooks to be enabled you should be very fine this way.
$config['enable_hooks'] = TRUE;
change to:
$config['enable_hooks'] = FALSE;
I hope this helps you.
I do not want the user to be logged out of the site even if the person is idle for, it is okay if the person is logged out if he has closed the browser.
session.gc_maxlifetime = 180000
session.gc_probability = 1
session.gc_divisor = 1
session.save_path = "/var/lib/php/session"
cookie_lifetime = 0
Is there any setting that i am missing?
Please help
To set the life time i have added the following code.
session_set_cookie_params(21600);
session_start();
You need extend your live time of cookie, remember that session id is stored in user webbrowser within cookie, set session.cookie_lifetime with a more big value too.
session_set_cookie_params(21600);
session_start();
21600 seconds is only 6 hours
Try setting to something bigger maybe even PHP_INT_MAX
Dont know whether it will help just wrote to give u the idea of how?....cookie are saved at user browser so ,
$cookieName = "userscookie";
$lifetime = time() + (60*60*24); // one day life
if(isset($_COOKIE[$cookieName])) {
$value = $_COOKIE[$cookieName];
// one day life from day of access
setcookie($cookieName, $value, $lifetime);
} else {
$value = "this value to store";
setcookie($cookieName, $value, $lifetime);
}
output:
Thankyou