I have a tricky problem; I've had it for a month or so so I have researched extensively.
I have a CodeIgniter site that is hosted - not by my choice, nor anything I have the power to change - by a third party, on 2 servers, load balanced by a third. The fun part is that the load balancer chooses at random the server, there are no sticky sessions.
Now, by default CI is supposed to handle this, using either cookies or storing the session in the DB. We've got the session set to autoload,
$autoload['libraries'] = array('session', 'user_agent', 'rest_client', 'lib_log');
The config has this in place for session and cookies:
/*
|--------------------------------------------------------------------------
| 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'] = 'e1fdc095-98e2-4294-9584-362ba355bacf';
$config['sess_expiration'] = 3600;
$config['sess_expire_on_close']= TRUE;
$config['sess_encrypt_cookie'] = TRUE;
$config['sess_use_database'] = FALSE; // obviously used TRUE when trying to use DB
$config['sess_table_name'] = 'ci_sessions';
$config['sess_match_ip'] = FALSE;
$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'] = "";
$config['cookie_domain'] = "";
$config['cookie_path'] = "/";
$config['cookie_secure'] = TRUE;
$config['cookie_httponly'] = TRUE;
(I am hoping against hope that something in that config is wromg? sess_cookie_name too long? sess_match_ip should be true?)
1) With cookies: the site works on a single node, but session disappears when the request is directed to another server. When the request is directed to the original server, session is back. This often (but not always - sometimes the user strikes it lucky and all requests go to one server) leads to infinite redirect loops (until the browser stops trying).
Interestingly in this case the standard behaviour upon login is to move from the controller/method (A/login) that creates session, to a method in another controller (B/index), to a method in the same controller (B/welcome). It is always B/welcome that fails to recognise the session, and redirects back to A/login. Then the loop starts, as A/login recognises the session.
2) With database: the session is not created, and apparently ( I am unable to monitor the DB ) the session is not created in the DB either. This has not been fully explored, partly because a unique ID for the session in the DB would have to be stored on the client, and the only place for that is a cookie. If using a cookie at all, why use a database?
(also the 3rd party hosts rolled back that attempt and it's pretty hard to get them to do anything further)
So I have a site that works 100% on my (single) server, on their servers, if the load is entirely on only one server, but fails when the load balancer is operating as expected. This is true of both the cookie and DB storage methods.
I am at my wits end. If anyone has any possible solution, or suggestion, please let me know.
I finally got access to a similar setup, and replicated the problem. However, I also solved the problem.. I just don't know how. It was through hacking and eventually replacing the entire /system folder of CI that I got it to work.
FWIW, the config settings above
$config['cookie_secure'] = TRUE;
$config['cookie_httponly'] = TRUE;
did not work; cookie_secure needed to be false even though the site had a cert. I've read elsewhere that the way the cert is installed in a load balanced environment can affect this. cookie_httponly is non standard and apparently has no effect.
Sorry I don't have anything better to suggest.
Related
I am working on OTP based authentication system. I want to keep the OTP code in a session variable. and it must forget in 5 min in generating time. is it possible to use session or do need to use cookies?
$otp_code = random_int(10000, 99999);
session()->get('otp_code');
session()->forget('otp_code');
$session = Session::put('otp_code', $otp_code);
There's a variety of answers regarding detecting IF the session has timed out. I am NOT asking that.
I am asking, how can I tell exactly how much time is remaining the user's Laravel session.
Assume I am using the latest version of Laravel.
I am strongly interested in knowing what the Laravel subsystem thinks is the time left remaining before it's native/built-in session timeout expires.
I am strongly against rolling my own, or creating my own custom timer of any sort.
Not that it matters, but my session lifetime setting configuration (session.php) looks like this (below). And my .ENV setting is also SESSION_LIFETIME=10.
/*
|--------------------------------------------------------------------------
| Session Lifetime
|--------------------------------------------------------------------------
|
| Here you may specify the number of minutes that you wish the session
| to be allowed to remain idle before it expires. If you want them
| to immediately expire on the browser closing, set that option.
|
*/
'lifetime' => env('SESSION_LIFETIME', 10),
This question is very specific to the session handler in use. If you need to know the time remaining before it expires, you must calculate it manually depending on the session handler like so:
File session handler: remaining time = last modified timestamp of file + session lifetime - current timestamp
Cookie session handler: remaining time = cookie expiry time - current time
Database session handler: remaining time = last_activity column value in session table + session lifetime - current timestamp
Cache session handler: remaining time = cache ttl
The session drivers use different session handler implementations as follows:
Cookie driver: Cookie session handler
File driver: File session handler
Database driver: Database session handler
APC: Cache session handler
Memcached: Cache session handler
Redis: Cache session handler
I have a webservice that stores an authenticated users token in the HttpRuntime.Cache to be used on all subsequent requests. The cached item has a sliding expiration on it of 24 hours.
Secondly I have a vb.net app that is pinging this webservice every 15 seconds. It gets authenticated once, then uses the cached token for all subsequent requests. My problem is that the application appears to lose authentication at random intervals of time less than the 24 hr sliding expiration. However with it getting pinged every 15 sec the authentication should never expire.
I am looking for a way to view the HttpRuntime.cache to try and determine if the problem is in the webservice security methods or within the vb.net app. Can I view the HttpRuntime.cache somehow?
The webservice is part of a web forms site that was built with asp.net 2.0 on a Windows Server 2008.
The name of my key's were unknown as they were system generated guid values with a username as the value. So in order to view a cache collection that was unknown I used a simple loop as follows.
Dim CacheEnum As IDictionaryEnumerator = Cache.GetEnumerator()
While CacheEnum.MoveNext()
Dim cacheItem As String = Server.HtmlEncode(CacheEnum.Entry.Key.ToString())
Dim cacheItem2 As String = Server.HtmlEncode(CacheEnum.Entry.Value.ToString())
Response.Write(cacheItem & ":" & cacheItem2 & "<br />")
End While
Hope this helps others.
First off, HttpRuntime.Cache would not be the best place to store user authentication information. You should instead use HttpContext.Current.Session to store such data. Technically the cache is allowed to "pop" things in it at its own will (whenever it decides to).
If you actually need to use the cache, you can check if your item is in the cache by simply doing:
HttpRuntime.Cache["Key"] == null
I'm using CodeIgniter 2.1
I use CodeIgniter's session to handle whether a user logged in or not. And it works well. I'm storing the sessions to a database. here are a few of my session variables:
$config['sess_expiration'] = 3600;
$config['sess_expire_on_close'] = TRUE;
$config['sess_encrypt_cookie'] = TRUE;
$config['sess_use_database'] = TRUE;
$config['sess_table_name'] = 'user_sessions';
$config['sess_match_ip'] = FALSE;
$config['sess_match_useragent'] = FALSE;
$config['sess_time_to_update'] = 15;
I'm using such a low sess_time_to_update increment because I needed a way to monitor whether a user has closed or navigated away from the page. Since CodeIgniter updates the last_activity column at every update (15 seconds) -To check for idleness I make a query like below (I know it's not correct language/syntax):
if last_activity < (current_time - 25s) then I know that a user has probably left the page.
The concept works good but I'm wondering if there are any unseen problems with updating the session table so frequently??
Thanks!
if last_activity < (current_time - 25s) only means that no requests were made in the last 25 seconds, not necessarily that the user has left.
The last activity won't actually update every 15 seconds unless the user is making a request every 15 seconds. For instance, if I open a page and read it for five minutes, the last activity won't update until the next request.
I'm wondering if there are any unseen problems with updating the session table so frequently
Just the little bit of overhead of updating the session table and refreshing the cookie. 15 seconds is a very small time frame, but it should be fine if that's what you really need.
If you don't want to update the session every five minutes do the following changes.
go to the session.php file in the System/libraries/Session.php and set all parameters like below to blanks. It's working for me.
public $sess_encrypt_cookie;
public $sess_use_database;
I'm having a bit of trouble with Drupal 7 and removing session variables I've set.
Things work as expecting when adding an item (via: $_SESSION['products']['p123'] = 'my product') and then removing (via: unset($_SESSION['products']['p123']) ) - which would leave me with an empty$_SESSION['products'] array.
But when I attempt to add another item (such as $_SESSION['products']['pABC'] = 'another product'), I would suddenly have both 'p123' and 'pABC' as keys in my $_SESSION['products'] array, even after the initial deletion of 'p123'.
Do I have to explicitly tell Drupal 7 that I've deleted an item out of my SESSIONS and to save that change? I hadn't had this issue using Drupal 6.
Turns out this was because of shifting from HTTP to HTTPS.
I was making my additions on a page served over HTTP, and my deletions on a page served by HTTPS. It seems that drupal keeps separate session variables for both secure and insecure connections, and will push the insecure session to secure when that transition is made.