When trying to design for stateless services one finds it easy to reduce the information stored in an http session but for one piece: whether the client has authenticated against the server or not. Usually you would implement a proccess for authenticating like this:
- Client submits credentials (login / password) to the server
- Server checks the credentials
- Server either rejects the login attempt or
- Server creates an http session and marks the successful authentication in there
From now on, every request will resubmit the session id which the server can look up in its session store and find out quickly whether the user has authenticated or not. So far so good.
The downside is that a session takes up some memory, needs to be considered when loadbalancing and forces your users to log in again after a server crash.
A way to do away completely with sessions is by encoding all the necessary information directly into the cookie. The initial sequence looks now like this:
- Client submits credentials
- Server checks credentials
- If failed, server rejects login attempt
- If succeded, server encodes user id, login timestamp and possibly access rights into a response cookie
From now on, every client request to the server will resubmit the cookie which the server can decode and infer the user id and access rights without maintaining a session.
For either performance reasons, or because your client might be interested in knowing his user id (i.e. service calls), the session cookie might be hashed (remember to salt it!) instead of encrypted, i.e:
userid,timestamp,accessright,hashcode
The encoding scheme allows for timing out “virtual” web sessions by that the timestamp for each request is outside certain timerange which is considered to cover valid sessions. Revalidating sessions is just as easy, if the timestamp of a request is withing a timerange cookie is replaced with the actual timestamp and updated hashcode.
A word on performance: 2.1 Ghz laptop runs around 60 encryption/decryption cycles (AES256) or 280 hash/rehash cycles (MD5), so you might prefer hashing instead of encrypting.