I have a site that is delivered by PHP and every user has a Session stored in a php file when he is logged in.
My Question is: it is possible, without redis or memcached, to get the session from the php file to the node.js server or if not, how can I do it with redis an memcached?
No matter how you store your PHP sessions, if you want to share data with an outside application, it should be served up from your PHP application. This gives you the flexibility of changing your session handling later on, while avoiding writing some custom session data parsing code on your Node.js application.
<?php
session_id($_GET['sessionId']);
echo json_encode($_SESSION);
Then in your Node.js application, you can fetch /getSessionData.php?sessionId=0123456789abcdef or whatever. Note that you must lock this script down so that it is completely inaccessible except from your other applications. Otherwise, you would be opening yourself up to a nasty security hole. Also, if you aren't already rotating session IDs, you should re-write your session handler anyway so that it is hard to re-play requests with an old session ID.
Related
Hi I have to retrieve data from several web servers. First I login as a user to my web site. After successfull login I have to fetch data from different web servers and display. How can I share a single session with multiple servers. How can I achieve this?
When I first login it create session and session id saved on temp folder of that server. When I try to access another server how can I use current session that already created when I logged in. Can anybody suggest a solution?
You'll have to use another session handler.
You can:
build your own (see session_set_save_handler) or
use extensions that provide their own session handler, like memcached
In complement to all these answers:
If you store sessions in databases, check that garbage collecting of sessions in PHP is really activated (it's not the case on Debian-like distributions, they decided to garbage sessions with their own cron and altered the php.ini so that it never launch any gc, so check the session.gc_probability and session.gc_divisor). The main problem of sessionstorage in database is that it means a lot of write queries and a lot of conflicting access in the database. This is a great way of stressing a database server like MySQL. So IMHO using another solution is better, this keeps your read/write ratio in a better web-database way.
You could also keep the file storage system and simply share the file directory between servers with NFS. Alter the session.save_path setting to use something other than /tmp. But NFS is by definition not the fastest wày of using a disk. Prefer memcached or mongodb for fast access.
If the only thing you need to share between the server is authentification, then instead of sharing the real session storage you could share authentification credentials. Like the OpenId system in SO, it's what we call an SSO, for the web part you have several solutions, from OpenId to CAS, and others. If the data is merged on the client side (ajax, ESI-gate) then you do not really need a common session data storage on server-side. This will avoid having 3 of your 5 impacted web application writing data in the shared session in the same time. Other session sharing techniques (database, NFS, even memcached) are mostly used to share your data between several servers because Load Balancing tools can put your sequential HTTP request from one server to another, but if you really mean parallel gathering of data you should really study SSO.
Another option would be to use memcached to store the sessions.
The important thing is that you must have a shared resource - be it a SQL database, memcached, a NoSQL database, etc. that all servers can access. You then use session_set_save_handler to access the shared resource.
Store sessions in a database which is accessible from the whole server pool.
Store it in a database - get all servers to connect to that same database. First result for "php store session in database"
I am writing a brand new website and I'd like to make sure that it scales out easily if I ever get to the point where I must host the site on multiple machines with a load balancer.
The user of the website can be authenticated. In other words, I need to maintain some state information. My first reflex was to use Session variables but then I am going to be limited to a single machine. I know that there are ways to store the session variables outside (in a DB, redis, memcached) but is that the only options?
What are the alternative to session variable? How Facebook and other big web sites are doing this?
P.S. I am not looking for another session handler (DB, redis, etc.). I'd like to know if there a way to completely get rid of session variables.
Ever heard of session_set_save_handler? It allows you to use mechanisms other than the default PHP session handler (the one that writes sess_xxxxxxxxxxxx files in tmp directory).
You can write your own session handler that uses a database. This could be a time consuming task; so you can stick with the default PHP session handlers for the time being and transparently switch to database when you are ready. You probably won't have to rewrite any code except implementing and plugging in your version of the six session handling functions.
You can look into caching, i.e using Zend cache or APC cache, for example.
I'm on board with the whole cookieless domains / CDN thing, and I understand how just sending cookies for requests to www.yourdomain.com, while setting up a separate domain like cdn.yourdomain.com to keep unnecessary cookies from being sent can help performance.
What I'm curious about is if using PHP's native sessions have a negative effect on performance, and if so, how? I know the session key is kept track of in a cookie, which is small, and so that seems fine.
I'm prompted to ask this question because in the past I've written my web apps and stored a lof of the user's active data, preferences, and authentication information in the $_SESSION variable. However, I notice that some popular web applications out there, like Wordpress, don't use $_SESSION at all. But sessions are easy to use and seem fairly secure, especially if you combine it with tracking user-agent / ip changes to prevent session hijacking. So why don't Wordpress and other web apps use php's sessions? Should I also stop using sessions?
Also, let me also clarify that I do realize the server must load the session data to process a page request, but that's not what I'm asking about here. My question is about if / how it impacts the network performance, especially in regard to the headers being sent / received. For example does using sessions prevent pages or images on the site from being served from the browser's cache? Is the PHPSESID cookie the only additional header that is being sent? These sorts of things.
The standard store for $_SESSION is the file-system with one file per session. This comes with a price:
When two requests access the same session, one request will win over the other and the other request needs to wait until the first request has finished. A race condition controlled by file-locking.
Using cookies to store the session data (Wordpress, Codeigniter), the race-condition is the same but the locking is not that immanent, but a browser might do locking within the cookie management.
Using cookies has the downside that you can not store that much data and that the data get's passed with each request and response. This is likely to trigger security issues as well. Steal the cookie and you've got the data. If it's encrypted, an attacker can try to decrypt it to gain the data stored therein.
The historical reason for Wordpress was that the platform never used the PHP Sessions. The root project started around 2000, it got a lot of traction in 2002 and 2004. As session handling was only available with PHP 4 and PHP 3 was much more popular that time.
Later on, when $_SESSION was available, the main design of the application was already done, and it worked. Next to that, in 2004/2005 wordpress decided to start a commercial multi-blog hosting service. This created a need in scaling the application(s) across servers and cookies+database looked more easy for the session/user handling than using the $_SESSION implementation. Infact, this is pretty easy and just works, so there never was need to change it.
For Codeigniter I can not say that much. I know that it stores all session information inside a cookie by default. So session is just another name for cookie. Optionally it can be encrypted but this needs configuration. IIRC it was said that this has been done because "most users do not need sessions". For those who need, there is a database backend (requires additional configuration) so users can change from cookie to database store transparently within their application. There is a new implementation available as well that allows you to change to any store you like, e.g. to native PHP sessions as well. This is done with so called drivers.
However this does not mean that you can't achieve the same based on $_SESSION nowadays. You can replace the store with whatever you like (even cookies :) ) and the PHP implementation of it should be encapsulated anyway in a good program design.
That done you can implement a store you can better control locking on (e.g. a database) and that works across servers in a load balanced infrastructure that does not support sticky sessions.
Wordpress is a good example for an own implementation of sessions handling totally agnostic to whatever PHP offers. That means the wheel has been re-invented. With a view from today, I would not call their design explicitly innovative, so it full-fills a very specific need in a very specific environment that you can only understand if you know about the projects roots.
Codeigniter is maybe a little step ahead (in an interface sense) as it offers some sort of (unstable) interface to sessions and it's possible to replace it with any implementation you like. That's much better for new developers but it's also sort of re-inventing the wheel because PHP does this already out of the box.
The best thing you can do in an application design is to make the implementation independent from system needs, so to make the storage mechanism of your session data independent from the rest of the program flow. PHP offers this with a pretty direct interface, the $_SESSION array and the session configuration.
As $_SESSION is a superglobal array you might want to prevent your application to access it directly as this would introduce global state. So in a good design you would have an interface to it, to be able to fully abstract away from the superglobal.
Done that, plus abstraction of the store plus configuration (e.g. all in one session dependency container), you should be able to scale and maintain your application well over as many servers as you like for whatever reason. Your implementation then can just use cookies if you think that's it for you. However you will be able to switch to database based session in case you need it - without the need to rewrite large parts of your application.
I'm not 100% confident this is the case but one reason to avoid the built-in $_SESSION mechanism in PHP is if you want to deploy your web application in a high-availability web farm scenario.
Because the default session behavior in PHP is to store session objects in process, in memory, it makes it hard (if not impossible) to have multiple servers processing requests from the same user. You would only have this if you wanted to deploy your web application in a web farm environment where you have a number of PHP web servers processing requests for your app to balance the load.
So, while in-process session state is generally much faster than a database-based solution, the latter is favorable when you need to process a huge number of requests and to service the capacity a web-farm environment is used.
As I said in the beginning, I'm not 100% sure if PHP supports configuring the session state provider to be a database, or session state server, instead of the in-process default.
Say I have a caching system that i can use for storing sessions:
// example i have a cache class
$memcached->add('key','value');
// then i can get the session from
$memcached->get('key');
What are the advantages and disadvantages of using caching (e.g. memcached, maybe Redis can fit in, or other things) for sessions rather than using PHP's built-in sessions?
I want to start by clarifying. When you're using PHP session storage, the sessions are being stored in a file (usually in /tmp). Each session becomes it's own file.
When you use memcached or redis to store sessions, nothing in your PHP code changes.
You can simply configure php to use redis or memcache to store the sessions instead (configured via session save handler in php.ini).
Pros:
session storage/retrieval becomes much much faster
cons:
you need to configure php.ini (or implement the session save handler yourself)
now, I would actually recommend using redis instead of memcache, simply because the sessions will become permanent, so if you need to reboot the server, all your users wont get logged out.
For redis:
https://github.com/owlient/phpredis (see "session handler" lower on the page)
You should be able to have PHP store session data in Apache's runtime memory by setting session.save_handler to mm. However, to do this you need to compile PHP with the memory management module (--with-mm), which I don't think is available for Windows.
If you want to use memcached or some other caching mechanism, then it'd probably be best to implement user-defined storage handlers using session_set_save_handler so you don't have to rewrite your session management code.
If you do that, then I don't think there are any obvious disadvantages to storing session data in that way. The obvious advantage is speed.
Edit:
I came across this page which discusses, aside from speed, the main advantages/disadvantages of using memcached for storing sessions, namely:
It's easy to share sessions across multiple webservers without using sticky sessions.
However, memcached makes no promises of keeping the data up until expiration—only that the data will not be available after expiration. So if memcached is low on ram, hasn't been used lately, or the server goes down at all, the session data will be lost.
I am trying to create a more secure PHP sessions login script. Unfortunately for this project I will be working with shared hosting. Would using PHP's session_save_path() function to change the path to something other than /tmp be a secure solution? Or do I need to save the sessions in the database?
Thanks!
Personally, I prefer storing sessions in the database because it not only circumvents some of the file access slowdowns associated with using a file-based system, but also gives you more direct and "supervised" methods of managing the direct session data.
Consider, if you implement using MySQL, using the Memory (HEAP) Storage Engine as it will give enormous performance benefits. This, of course, is assuming you are unlikely to have thousands upon thousands of active sessions, and that your session data is "volatile safe," i.e. if a sever crash causes session data to be lost, the worst that should happen will be that users are asked to log back in.
Moving the session save path is a good start. Just make sure its not in the document root.
With some shared hosted I've observed that getting a database connection can take a second or two. Storing your sessions in the db could slow the whole app down. Your session is accessed twice per page load.
You may want to test both an see which performs better.