I am struggling to find info on PHP's session_set_cookie_params() affect on sessions that are being stored in a database. Have searched SO and google and referred to the manual, but no luck.
1) Is this function still used in exactly the same way as when using the default file storage for sessions?
2) A more generic session question then (file based approach) - when a session expires, is it deleted from the file system, or does that take place with the auto 'garbage collection', the probability of which is set in php.ini?
3) How is the first parameter (session lifetime) handled when using a database to store the session data? Because without a custom function/method, deletion from the database is not possible. Or does the session expire in the same way as file approach, but the garbage collection needs to be handled with a custom function?
I'm using the following article as a go-to at the moment;
How to save PHP sessions to a database
Thanks in advance.
1) This function configures the cookie that php sends to the client so it works as expected. The session_set_cookie_params() function only applies if you use the default PHP session implementation which stores session data on the disk in the folder defined by session.save_path
2) When using php's session implementation garbage collection happens automatically based on the session.gb_* ini settings. Each time a session is started there is a probability that the garbage collector is ran which will clean up all data from expired sessions.
3) You'll need to implement your own garbage collection routines if you use database storage for your sessions. You can use the probability ini settings to determine when to run garbage collection (see gb_probability and gb_divisor). Garbage collection is performed right after starting the session in most cases. That's when you should see if it should run, and if it runs query your database and remove all stale records. This assumes you also store expiration data with your records so you can actually evaluate if the record is stale or not.
That being said, don't reinvent the wheel and use one of the many Session libraries that already implement custom save handlers.
http://framework.zend.com/manual/current/en/modules/zend.session.save-handler.html
http://symfony.com/doc/current/components/http_foundation/session_configuration.html
Related
I'm using Laravel 5.7. Redis is set up as my cache and and session driver.
In my controller, if I write to my session using either $request->session()->put() OR Session::put(), it will show up when I print my cache for the session id:
print_r(unserialize(Cache::get(Session::getId())));
Note, my primary goal in outputting session data this way is to access sessions that are not my active session.
However, if I write to my session using either of these methods down the line in my domain, they will NOT show up in the cache print, but will show up (along with everything else that does show up in the cache print) if I use:
print_r(Session::all());
I'm perplexed as to what is going on. I verified that what I'm saying is also true when accessing data via the redis cli. Apparently if I write to session in the domain, it is stored somewhere else somehow? Thoughts?
Your cache and your session are two totally different entities, even though they can use the same driver.
A session is used to maintain a relationship with a user. See the PHP session documentation for more details.
A cache is a place where you store and look for commonly accessed data, instead of hitting expensive code or the database. It is ephemeral, and is never guaranteed to hold any data whatsoever.
Why don't you just use Session::get('whatever')?
After seeing your edit:
Note, my primary goal in outputting session data this way is to access sessions that are not my active session.
You should store that data via a more durable storage mechanism than your cache. As I mentioned before, a cache is ephemeral. You can use redis, as it's a key-value store and not a true cache like memcached. Just use it directly as such:
Redis::get('user:profile:'.$id);
i am trying to communicate with Memcache as a session handler for Joomla. Following the PHP docs bottom example i have registered memcache a session handler. As soon as a user loads the Joomla site its session id together with other user data is stored into the Joomla database. But now i don't know how to get hands on Memcache to read the serialized session data like can be done with XCache using xcache_get($sessionid) As soon as i create a new Memcache instance as can be seen in the docs top example the session entry is removed from the database. But the session yet exists. This is quite confusing to me. I required to access (read/write) the serialized user session. How can i fetch/set it from the PHP session handler?
I believe the equivalent you are looking for is something like this:
Getting the session:
$session = $memcache->get($sessionId);
Setting the session:
$memcache->set(
'sessionprefix:'.$sessionId, // the session id.
$session, // the actual session itself
false, // set to true to use compression
$expire, // expiration in second
);
I have not used memcache very much but I have read that people usually use a prefix in the key to separate the different types of objects (this is also a common practice with redis, a similar data store). I have used 'sessionprefix:' here but I am sure Joomla has their own specific prefix.
I'm storing the sessions ids in a database table. I
want to run a script that reads from the table every
session id and check if this session is active or not.
I know that session information is stored in a
directory (/tmp by default) and removed from there
when the session is closed. But if the user close his
browser without disconnecting from the session the
session file is still in the /tmp directory.
How can I know if a session is still active or not?
I have searched the session functions and didn't find
anything that could help.
Generally speaking, the only way is to have a "last used" datetime/timestamp which you update every time the session is referenced, and discard/deactivate sessions after they haven't been used for a certain amount of time.
It's not possible to tell if a session will be referenced further as they're not kept open between requests, simply referenced when needed ... and need is dictated by the ever fickle client.
If your sessions are file based, as it sounds, you can use the last accessed date of the individual files, possibly save yourself a bit of trouble.
If you are keeping sessions in the database. Add a last accessed or modified timestamp to the database table. I've put code in my procedures that retrieve or store session information that DELETE FROM sessions WHERE modified is more than an hour ago. However long you want your session to be. At every call you can update that timestamp. It seems that would cause a performance hit, but I've used that pattern/process quite a bit. I almost always use the database to store session information. You should research session_set_save_handler(). I can try to gather some of my own code from previous project where I utilized this, but I'm sure that reading the manual on this and googling implementations will help you quite a bit.
Why would you care about this already outdated sessions? They will be cleared from temporary folder in some random time anyway.
You should check last access time in your database and if it's more then some predefined timeout - mark it as dead.
But think about your performance too. It's a way better approach to store your session data in memcache or something similar to it - just store it in memory, not in DB. Read more about it here: http://memcached.org/
It's really easy to store your session data in memcached: http://www.dotdeb.org/2008/08/25/storing-your-php-sessions-using-memcached/
There isn't such a function.
PHP itself use somewhat an hack to determine when a session is expired, there are several
options into the php.ini configuration file.
In short, every time a session started there is a gc_probability/gc_divisor chanche that php will start a
garbage collection of pending data.
The session accessed before gc_maxlifetime seconds are considered expired and PHP deletes them.
You can relay on this behaviour tuning the envolved options or mimic this behaviour with a
similar approach.
For reference:
http://it.php.net/manual/en/session.configuration.php#ini.session.gc-maxlifetime
http://it.php.net/manual/en/session.configuration.php#ini.session.gc-probability
http://it.php.net/manual/en/session.configuration.php#ini.session.gc-divisor
Does anyone know how PHP maps session IDs to $_SESSION arrays? In other words, given session ID x, where does PHP pull the values from to populate the $_SESSION array?
And given a session ID and the url it came from, is there any possibility of someone being able to gain access to the values in the $_SESSION array?
By default, PHP uses the files session handler. These files are stored based on the session.save_path setting, but defaults to the system's temp directory (a highly insecure location, consider changing it)
This session handler stores each session as a serialized PHP array in a file named with the session ID.
If you can find out a session ID prior to it being cleaned up by the session garbage collection routine, it can be hijacked, as PHP does not internally do any sanity checks. You may wish to do your own by storing the user's IP address in the session and comparing it to their current IP, clearing the session if they don't match.
session.gc_maxlifetime controls how many seconds a session will be considered valid. After this point, the session has a small chance of being deleted every time a request occurs. Default is 1440 seconds (or 24 minutes).
By default, this chance is 1%, but can be altered by adjusting the session.gc_probability and session.gc_divisor values (they default to 1 and 100 respectively).
There are other session handlers as well, such as the ones included with the memcache or memcached extensions. There was once one based on the libmm shared memory library, but I believe that has been discontinued.
Session info is stored on server filesystem. There's configuration parameter session.save_path in php.ini. Some info about sessions security is given here: http://www.php.net/manual/en/session.security.php
Session data is usually stored in temporary files on disk (see the session.save_path setting) and the filename reflects the session ID.
In general, yes, if someone gets hold of another user's session ID and sends it along with his own request, he will gain access to that user's session. One way of solving this is to bind sessions to IP addresses and invalidate the session when a request arrives from a different address.
No, there is no possibility!
...unless your code or the code of any component used is insecure.
With the default implementation of sessions (which can be replaced by a custom one if needed) the data is stored in local files. Your server receives the session ID from the client in a cookie, finds the corresponding local file on your server and populates data into $_SESSION.
Gaining access to this data requires file-level access on the server, which is not impossible, unless your server is secure enough.
You can also write your own session handler to save the session to a database.
Also, if you want to make it harder to pin down the session ID, regenerate the session ID at strategic times (on privilege elevation, etc) -- or as often as you want.
Pass session_regenerate_id() the argument True to destroy the old session data.
In general, I have the following scenario:
Fetch product and its related data from database
Convert fetched data to php 'product' object
cache product object in session
The cache is readonly, i.e customers viewing products on the site.
But there are calls like getProductIdsByCategory($categoryId) and the productIds from these results are cached too, per user, not using the global cache that I've read about.
A problem is that if someone on the admin side adds a new product and relates it to a category, then customers will not have the new productId come up in their cached getProductIdsByCategory until a new session is started.
Is there a way to clear e.g $_SESSION['x'] from ALL sessions on the server when a new product is added? I don't want to destroy all sessions because customers will then lose their logins etc.
Or should I move these cached productId searches to the global cache?
p.s am using a custom built cache, not memcached or similar.
Thanks
By default, the session data is just serialized files somewhere in your filesystem, and it is possible to go modify all of them to remove the information in question (respecting locking so that you don't step on any currently open sessions).
I don't really recommend it, though. What I would recommend is making a method of signalling that this cached data should be refreshed, like a database-stored timestamp that gets looked at when session_start() happens, and if the cached data is older than the timestamp, the cache is flushed.
Sounds to be like you could do with real shared state through a caching system like memcache.
The only other way that prints to mind is have the application check for flags for dirty cache data and delete it itself, or if your cache is in a database in a parsable serialized form write an expensive script to read them all, but that will create nasty lag with requests that have already read the data.
I would go with real shared state than checking for object copies.
Unless you store sessions in a database, clearing any specific bit of data will be tricky.
I would suggest caching in files rather than user sessions. This way you achieve the same benefits, but you get total control over what is cached and when it gets cleared.
To disable all existing sessions for a particular application, simply modify your application to change the name of the session using PHP's session_name('new_session_name'). This function needs to be called before each call to session_start().
This won't actually clear the current sessions, but it renders them no longer useful for this application.
Yes, you should move it to a global cache. Sessions are not meant to be accessed globally, I hardly think it's possible.
<?php session_destroy(); ?> // To delete whole session
// OR
<?php unset($_SESSION['myVar']); ?> // To delete a session myVar
to clear a session value use:
unset($_SESSION['x']);
you may loop on sessions for that