posted 10-Sep-2012 | 14 comments | , , , , , , ,

Almost all of the web apps we build nowadays (at least on the circles I usually move around) rely on the beloved and hated session. This artifact, providing a stateful user wide storage, allows us to relate several HTTP requests together and thus implement the concept of authenticated and secure web applications, that “know” who is using them several requests after they authenticated, despite the root stateless characteristic of the HTTP protocol itself.

To provide a very brief recap, sessions are usually implemented using a hash like memory structure on the server, where each session is stored using a unique identifier string. This string is stored also on the users web browser, typically via a cookie or by sending it back and forth on each request as a POST or GET parameter.

I believe it’s time to move away from this approach and start building session-less web applications that still provide the same feature set and security.

You might say that this is part of a REST approach to web applications and that it’s been already beaten enough into our heads… but the truth is it’s not, most of the new apps I see are still making heavy use of session storage and their whole architecture is based around it.

Why are session based web apps bad for us?

So why? Why are we supposed to stop using this thing we have been using for 15 years of web development? Well, session variables are no more and no less than global variables and if you still need arguments against the usage of global variables please either go back to college or ask for a refund.

Still not sure? Some stuff why session variables are mean:

  • They promote coupling: disparate pieces of code access the same variable without a defined contract
  • They reduce scalability: over usage of session storage increases the app memory usage as the user base increases
  • They promote harder to read/debug code: some page/method accesses a session variable that “magically” contains the value you need but it’s usually unclear where this data came from and who put it there.

Ok, you convinced me, now what?

Easy, just stop storing stuff on that session!! No, really, stop it!

I bet that in 99.9% of the use cases, you can build your app by just knowing who the user is. So what you must do is just store the user identification on the session and that’s it.

But you will say: ohhhh, but really, I mean, we display his first and last name on every page, isn’t it just easier and faster if we store them too on the session?

And let me tell you, it’s like crack, you don’t want to go down that road. Keep your architecture pure and stateless, let every controller method receive the information it needs from the HTTP request and return all the information the view needs to render itself. If you are worried about IO performance, implement an appropriate caching strategy on the data access layer, do not use the session for performance tuning.

  • java

    I thought you will tell about completely skipping configuration of session but if you keep USER ID in session then you can’t escape from it or probably the title of article needs a change

  • http://ricardozuasti.com/ Ricardo Zuasti

    You know I indeed gave it some thought since it can be misleading, but honestly I couldn’t figure out any other appropriate title. If I do I’ll change it, I really don’t like to lure people and then don’t meet the expectations.

  • Liyu

    so you get rid of the session, and let user tell your app who he is, so he can pretend another people?
    so Joe hit login page and login as Joe, and he can pretend Jane later by change some URL string or fake a form? I’m not sure if your bank is doing that, will you still use it?

    Frankly speaking, you barking on a wrong tree, if the app needs state, you have to store some where, client side is not safe place, session or DB which is too expensive.

    BTW, the stateful web app doesn’t mean only login, there are context and some kind of flow with it. you mute those too.

    Dude, please think twice before you really write this!!!!!!

  • http://ricardozuasti.com/ Ricardo Zuasti

    Hi Liyu, the whole idea is to store the user identification in the session, just that and only that. That doesn’t mean to take it for granted from each request.

    If you are developing an authenticated app you probably have a login action/controller/etc that validates the users credentials, you should set the user ID on the session after such use case completes successfully (and only then), so subsequent use cases can take the user ID from the session and trust the user ID stored there has been authenticated.

    If you do not trust the session storage of your web server, then you need a new one :) Session hijacking, while possible sometimes due to exploits and poor code design is a problem, but the solution is not to ask the user to authenticate himself on each request, not to store his credentials on the session.

    Regarding web apps with complex work flows, for example a multi-step form, I prefer a design approach where the state is transfered from step to step, either via request/response forwarding or kept on the browser if the app is AJAX based.

    I hope it’s clear now :)

    cheers

  • Liyu

    So it’s like by saying “You can float in the air”, and you really mean “sit on the chair, and keep you feet off ground”?

  • http://ricardozuasti.com/ Ricardo Zuasti

    I didn’t get that one :)

  • http://ricardozuasti.com/ Ricardo Zuasti

    another one

  • Gergely Polonkai

    So you would store the so called session on the browser? You mean the thing over which the user (let’s just suppose it’s the user, not some kind of attacker) has total control? No, I don’t think it would be right. Sessions, if implemented well, can help you a lot during web application development. Unfortunately(?), HTTP is a stateless protocol, so you have to put some kind of state related information on it. A cookie is just good for that, and if you check it, together with other data (IP address, browser type, etc.), you already have a so called secure session storage. Of course, if you don’t trust your web server, you can put the storage in the database (although if your web provider is malicious, maybe their database is leaking, too). And if you don’t like globals, abstract the whole session thingie in a Session class.

  • http://ricardozuasti.com/ Ricardo Zuasti

    Gergely, hi. I’ll try to give you my opinions on each of your points:

    * Storing session on the browser : I infer either one of two things from this
    1. If you mean the session ID is stored on the browser, of course it is. All session handling implementations rely on the browser in some for or another, they either use a cookie or sent the ID back and forth via a response parameter.
    2. If you mean storing the session data on the browser, well, you could, but why would you? Even though I don’t advocate for “big” sessions, I think its better to use the web servers memory than a cookie on the browser (unless of course for long lived sessions that span longer than the actual web server session).

    * Trusting the web server: I believe you have to in order to be productive as a web developer, of course you should create the most defensive code possible, but if you start doubting your web server features (such as session tracking, cookie handling, etc.) you will end up developing a custom web server on top of your existing one, and I would bet it will be a lot more buggier :)

    * Using a session class to avoid globals: I was talking about global variables as a broad design concept, ie. having a memory space that several disparate software components access in an unrestricted fashion. In that scenario having the global variables wrapped around a class or in a map or array doesn’t change the approach, it’s still a “global variable” of sorts.

    r.

  • Nani
  • plog

    Agree with Gergely Polonkai, just abstract your session handling with classes and manage all data in restricted/managable form, who cares how that class stores its data? In OOP design we don’t care low level stuff which is going under the hood. Singleton is a must because there is only one resource as ‘SESSION data’. You can for example create singleton SessionManager, and other class SessionData which communicates with session Manager. then extend that class to specify your custom data. for example:
    class SessionManager { // singleton
    function getInstance():SessionManager;
    function save(SessionData dataObject) {
    $_SESSION[dataObject.getIdentifier()] = serialize(dataObject);
    }
    }
    class SessionData {
    function setSessionManager(manager);
    function setInstanceName();
    function getIdentifier():String { return get_class(this). ‘.’ . getInstanceName(); }
    function constructor() {
    sessionManager = SessionManager.getInstance(); // default manager
    }
    function save() {
    sessionManager.save(this);
    }
    }
    class FormSessionData extends SessionData {};

    Is it bad for you anyway?

  • http://ricardozuasti.com/ Ricardo Zuasti

    I believe that even though this kind of encapsulation may provide a more controlled session access (though in most cases it just adds complexity and the application server provided session handlers are enough) it does not address the problems I presented.

    Of course this are design decisions and therefore matters of opinion :)

    r.

  • webstandardcss

    I hate the idea that you must think so many times before you write something online. Minds can be changed. Ideas dont need to be perfect. Thats what comments are for.

  • Gorka Lerchundi Osa

    Totally agree eith Ricardo, things are evolving elastic net is the new buzzy word and stateful servers are the evil. Go stateless and on backend and create stateful frontend.