To use, or not to use, session_set_save_handler? - php

I'm playing around with creating a user login system in php.
I have been studying this article (http://www.evolt.org/node/60384) as a way of approaching this.
In the above article, the author uses a combination of $_SESSION and his own custom database table for storing user info.
However...
I have also come across numerous articles that recommend using session_set_save_handler to configure php sessions to use the database natively. (Which I guess is a newer technique.)
I am wondering: If I am planning on setting up an "activeUsers" table in the database for recording session data anyhow, does it make more sense to use session_set_save_handler? (Seems if I'm using the database to store some session info anyhow, I might as well dispense with filesystem sessions.)
Or is there some advantage to leaving php sessions in their default filesystem form, and then x-checking user logins against my custom db table?
Thanks (in advance) for your help.

Storing session data in a database can be a little tricky to setup at first, but once you have a class or function set up to do this, then you get a few potential advantages over filesystem storage. The question is whether or not those advantages are required for your system. These are, I think, amongst the most common reasons for storing session data in a database:
Security: If using shared hosting, session data may be held in areas of the disk that are accessible by other users of the system. This could constitute a security risk for your application.
Scalability: If your application is handled by more than one server (a server farm, for instance_, you need to ensure that multiple requests from the same client, which may be processed by different servers, each receive the same session data. This is quite easy to do if the session data is in a database.
Performance: Database storage may give a performance increase over filesystem storage, but this is heavily influenced by the server configuration.
DB interaction: Depending on the role of your session data, and how your application uses it, it may be easier to retrieve session data and related information if it is all in a database.
Something else to consider is that you can enhance the session information by storing additional information, such as IP addresses, log on and log off times, and so on. This sort of information can be useful when trying to prevent session hijacking.
So, other than the scalability issue, I think it's all quite subjective. You need to weight up the extra work required to implement database session storage, with the possible benefits.

If you use it you need to make your own garbage collector.

Related

Symfony2 storing data in session versus database calls every page load

I have a site built on Symfony 2 that is basically made up of various applications. Once an application is selected, I store that application's ID in a session variable. Then for every page load for that application, the database is queried for the details of that application.
Wouldn't it be more efficient to just store the application details in the session variable instead of just the application ID?
What are the down sides of storing the application details in that way, are there any security risks I need to worry about?
Thanks a lot.
I do not recommend to store the app number at session at all. You deprive yourself from usage of shared HTTP caches with that approach http://symfony.com/doc/current/book/http_cache.html#public-vs-private-responses as all your requests become private cause a response depends on SESSION value.
If you will move the app number to the url or header or etc you will get a lot of space for optimizations.
Usage of the DB to a get app info is a quite good practice as you are able to enable doctrine's result cache for this queries to make them not impact of the app performance at all. http://doctrine-orm.readthedocs.org/en/latest/reference/caching.html#result-cache
Usage of the session to store app_id is bad practice but usage of the session to store the all app info is even worse as the number of session_ids is significant and you will store a lot of redundant information.

php session management in socket services

I'm considering building a security service in PHP that would hold user credential information , the most important of them would be tokens of logged in users. This service would be accessed by some kind of an API (REST, SOAP, whatever) by another API (an external user connects through a website API which checks credentials in another API - the one we're considering now).
There is a possibility to store tokens (and other information) in RDBMS. But this solution doesn't seem clean to me (tokens will remain in the database even if they're already expired, I would have to implement a mechanism for clearing expired sessions, etc). I was thinking about using native PHP session management ($_SESSION). Is that possible? Does anyone have experience with doing such things?
I thought of following problems:
when a PHP-based website is deployed on www server, users access the URL via browser and their native sessions are created using browser cookies. If there was one webpage API that would connect to security API, would there be only one session object all the time? Is it configurable?
How precisely sessions are created and how can I affect the mechanism (e.g. not to base it on cookies)?
My advice would be to use a database.
Let me start out with explaining the general concept of sessions. Sessions can be seen as server-side cookies. The location of the $_SESSION variable storage is determined by PHP's session.save_path configuration. Usually this is /tmp on a Linux/Unix system. Sessions have a session-parameter of the client associated with them. When a session_start or something like that is issued, the server will retrieve the file/session based on the session-parameter provided by client. As these are just stored files, it is possible for the server to read the sessions of other clients.
That brings me to the second problem you describe. If I am correct you want to have some api request information about a session of some user. Based on the first paragraph, you hopefully understand that the purpose of sessions isn't to use it as some sort of global storage. Of course it is possible. You could have the foreign APIs include the session-parameter or you could read the session-files manually, but to me these seem dirty fixes. It just isn't what sessions are build for.
The only other thing which attracts you to using sessions is the automatic timeout of sessions. However this simple logic you could easily implement when using a database. What you should do is register the time of the last activity of the user in your database. When an API requests the data of a user you can simply check whether the current time - the last active time is lower than a certain threshold. If that is not the case, the session expired and, at the same time, you can drop the session from the table. This is the more or less the same general method as sessions internally use, which requires no regular cronjobs (although they still could be useful to cleanup the database) to remove sessions.
So don't be afraid to use a database to store data, after all they are build (and optimized) to do that exact thing.

PHP - What data should we include in the session?

This is a beginner question...
In a website, what type of data should or should not be included inside the session? I understand that I should not include any info that needs to remain secure. I'm more interested in programming best practice. For example, it is possible to include into the session some data which would otherwise be sent from page to page as dependency injection. Wouldn't that correspond to creating a global variable?
Generally speaking, what kind of data has or hasn't its place inside a session table?
Thanks,
JDelage
The minimum amount of information needed to maintain needed state information between requests.
You should treat your session as a write-once, read many storage. But one which is rather volatile - e.g. the state of your underlying application data should be consistent (or recoverable) if all the sessions suddenly disappeared.
There are some exceptions to this (normally the shopping basket would be stored in the session - but you might want to perform stock adjustments to 'reserve' items prior to checkout). Here items may be added/edited/changed multiple times - so its not really write-once - but by pre-reserving stock items you are maintaining the recoverabiltiy of the database - but an implication of this is that you should reverse the stock adjustments when the session expires in the absence of completion.
If you start trying to store information about the data relating to individual page turns, you're quickly going to get into problems when the user starts clicking on the forward/back buttons or opens a new window.
In general you can put anything you like in a session. It's bad practice to put information in a session that has to be present to make your page run without (technical) errors.
I suggest to minimize the amount of data in your session as much as possible.
stuff you can save in the session so that you dont have to make another database query for info that isn't going to change. like their username, address, phone number, account balance, security permissions on your site, etc.
(This is perhaps more than you're looking for, but might make for good additional information to add to the good answers already posted.)
Since you mention best practices, you may want to look into some projects/technologies which can be used to take the idea of session state a bit further. One common pitfall with horizontally scaling web applications across multiple servers is maintaining session state between them. (User A logs in to Server A which stores the user's session, but on the next request hits Server B which doesn't know about User A's session, etc.)
One of the things I always end up saying to myself and to colleagues is that session by itself isn't really the best place to store data, even if that data is highly transient in nature. A web server is a request/response system, not a data store. It's highly tuned to the former, but not always so great for the latter.
Thus, there are ways to externalize your application's session data (or any stateful data, which should really be kept to a design minimum in the RESTful stateless nature of the web) from your web server and to another system. Memcached is a very common tool for this. There are also drop-in session replacements (or configurable session options for various frameworks/environments) which store session in a database like SQL or MySQL.
One idea I've been toying with lately is to store session data (well, any transient data where it's OK to lose it in a catastrophe) in a NoSQL database. CouchDB and MongoDB are my current top choices for this, but there's no shortage of other options. CouchDB has excellent horizontal scaling, MongoDB is ridiculously fast when run entirely in-memory, etc.
One of the major benefits of something like this, at least for me, is that deployments can easily become non-events. The web services on any given server can be re-started and the applications therein re-initialized without losing stateful data. If the data is persisted to the disk (that is, not entirely run in-memory) then the server can even be rebooted without losing it. Servers/services can drop in and out of the farm and users would never know the difference.
Additionally, externalizing this data allows you to analyze the data in potentially useful ways. Query it, run metrics on it, interface with it via other web applications or entirely offline tools, etc. It really opens up the options as a project grows in complexity.
(Again, this isn't really intended to answer your question, but rather to just add information that you may find useful. It's something my colleagues and I have been tinkering with as of late and your question seemed like a good place to mention it.)

Approach for authentication and storing user details

I am using the Zend Framework but my question is broadly about sessions / databases / auth (PHP MySQL).
Currently this is my approach to authentication:
1) User signs in, the details are checked in database.
- Standard stuff really.
2) If the details are correct only the user's unique ID is stored in the session and a security token (user unique ID + IP + Browser info + salt). The session in written to the filesystem.
I've been reading around and many are saying that storing stuff in sessions is not a good idea, and that you should really only write a unique ID which refers back to the user's details and a security token to prevent session hijacking. So this is the approach i've taken, i use to write the user's details in session, but i've moved that out. Wanted to know your opinions on this.
I'm keeping sessions in the filesystem since i don't run on multiple servers, and since i'm only writting a tiny tiny bit of data to sessions, i thought that performance would be greater keeping sessions in the filesystem to reduce load on the database. Once the session is written on authentication, it really is only read-only from then on.
3) The rest of the user's details (like subscription details, permissions, account info etc) are cached in the filesystem (this can always be easily moved to memory if i wanted even more performance).
So rather than keeping the user's details in session, the user's details are cached in the file system. I'm using Zend_Cache and the unique cache id is something like md5(/cache/auth/2892), the number is the unique id of the user. I guess the benefit of this method is that once the user is logged in, there is essentially not database queries being run to get the user's details. Just wonder if this approach is better than keeping the whole lot in session...
4) As the user moves throughout the site the only thing that is checked is the ID in the session and the security token.
So, overall the first question is 1) is the filesystem more efficient than a database for this purpose 2) have i taken enough security precautions 3) is separating user detail's from the session into a cached file a pointless task?
Thanks.
You're asking a range of things.
Sessions
Sessions in PHP are fast and efficient. Thousands of small disk-based sessions on a moderately up-to-date server is not going to be a performance bottleneck. Neither is writing your own handlers (very easy; the PHP manual has examples) to put it in a database.
About the only best-practice rules about sessions is: only give the web browser one thing, the session ID. Putting just the logged in userid in the session and retrieving those details from the DB when you need them is also best-practice. It also means that user information can be changed and they get it on the next page update.
It doesn't sound like you will have this problem but beware of just throwing a lot of stuff into a session. A few K of data (say, a few dozen scalars) is fine. Tossing many objects and large arrays of data in there will be noticed. If you do this for a specific page, remember to throw it away in the session once the page is done with it.
You may also want to implement your own login timeout with a session variable. The garbage collection settings in php.ini are intended for managing the storage of session data, not for doing login timeouts.
Caching
This is a complex topic and you will probably need to start gathering metrics (generally page load times) before implementing anything.
To implement any sort of caching, you do need to consider the lifetime of the data you're caching and how expensive re-generating it will be on a cache miss. Just throwing memcache at the problem is not a solution; you still need to understand your caching parameters and how memcache interprets them. This also applies to any persistent storage solution, including disk-based sessions, but I'm highlighting memcache because it is high-profile and has quite an aggressive expiry mechanism.
An often overlooked example is loading the same data from the database multiple times in a page: a good ORM will do that for you without relying on MySQL query caching. Another overlooked example are small queries that run on every page: caching these for just a few seconds on a moderately busy server and the database load will drop considerably.
Finally, caching at multiple levels is often much more effective and scalable than once because they can leverage each other's expiries. It also abstracts well: for example, hide it in your ORM and it's theoretically available invisibly and automatically for all your objects.
1) You can easily test which is faster by making a loop script. Anyway, a drawback with using the filesystem is that you need to update the cached file everytime you update the db. Copies of data is in general a bad thing. Also, unless you have millions of visitors I dont think there will be any practical diffrence regarding speed in any of the stratagies. And... not to forget, sessions are also stored in the filesystem. One file for each session.
Is a query faster then the filesystem: Depends. Is query caching enabled. In MySql it is by default, and than you might be lucky and only need a memory access. If not, the db needs to do a filesystem accass anyway. Second, how optimized is your query with index's. How buissy is the server harddisk.
3) Depends on the speed of fetching it from db. In general, caching can do magic to speed performance, but caching in memory would be even better by using memcached or something similar. In general i would avoid copies of the data in files. But of course, if it takes secods to query the data from the db, than go for filesystem caching. Also, if you have many users.. like 10.000+ you have to make some folder system, since putting 10.000 cached files in the same folder slows downs the accesstime...

Session variables

Hy guys. I'm currently working on a project which uses a lot of data stored in session variables. My question is how reliable is this method and if affects the server performance and memory usage. Basicaly, what you would choose between session variables and cookies.
In general, session variables are going to be a lot more secure in the fact that the user cannot edit them locally on his/her machine.
But the real question begs, what are you looking to store? With a bit more information we might be able to give you a better answer as to where you would want to store it :)
Edit:
If you are looking to store user actions, I might recommend building a UserActions table or something along those lines. A table that contains the following:
id INT (generic ID for the record),
timestamp TIMESTAMP/DATETIME (whatever your DB supports),
userid INT (lookup to the user table),
action VARCHAR (what action you want to record),
etc etc (whatever else you want to store)
Then when a user performs an action you want to record, just log it into the table itself, instead of making it travel along with the user in a session/cookie. Really the page itself doesn't need to know what actions the user has performed in the past, unless its a "multi-step wizard" type application. In that case, it probably would be best to pass them as a session variable.
Then you are pushing the storage into a true storage component (being the database) instead of session/cookie as storage.
I mean we still don't really have an idea of exactly what you are developing, but I hope it helps.
Session variables are generally preferable to cookies. That said, they are usually stored in the /tmp directory on your web server, which is world-readable and world-writable. This could be breeding ground for mischief if you don't control your server or you run in a shared environment. Not storing sensitive information in session variables, and not relying on them for stuff that has to work is a good practice.
You should only use cookies if you need the data-per-user to persist across sessions. That is to say, if they revisit the site outside of the session expiry time and you need the data there.
Otherwise, if the data is only for their current session, then go ahead and put it in $_SESSION. That what it's there for.
Session data is usually stored in files on the server or in database. So how many data is there depends only from your scripts. If you want to store big binary files in the sessions you will probably reach memory limits quickly.
Storing the data in cookies is not always a good idea. This data is visible to the client, he can easy change it and in some cases that just something you mustn't allow.
Session variables do not require submission by the user, they are simply loaded based on a session key. Memory usage depends on the session implementation since there is the cost of retrieving the session from your database (or file system, or memory, or w/e).
it's always a tradeoff between keeping information on the server (more memory used) and pushing some of that data off to the client machine (more bandwidth and less secure). As a rule of thumb, I prefer sessions, they are more secure and easy to manage.
When i wrote this question I was thinking at non-sensitive data and with application for logging user activity on website. I think that, for a busy server, with a large number of users, it's better to use cookies instead, it will unload the server resources(memory, hard-drive I/O). In terms of performance, I think that session variables are a better solution.
Anyway, I don't know how better it will scale the SV solution.
Using any session variables - at all - means that your application servers need to maintain session state with appropriate synchronisation.
This has an overhead and may negatively affect the scalability of your application, because every server needs to know about (potentially) every session - which is going to mean a lot of cross-server traffic for session data and synchronisation.
While you only have one server, it's ok.
When you get more and more servers geographically distributed, it gets more and more painful.
There is some overhead for the serialisation / unserialisation of the session, but in practice that's not such a problem as it will be relatively fixed per request, hence scalable to high traffic applications.

Categories