Search code examples
sessionhaskell-snap-framework

Why are sessions in the Snap Framework client side only?


By browsing through the code of the Auth and Session snaplets I observed that session information is only stored on the client (as an encrypted key/value store in a cookie). A common approach to sessions is to only store a session token with the client and then have the rest of the session information (expiry date, key/value pairs) in a data store on the server. What is the rationale for Snap's approach?

For me, the disadvantages of a client side only session are:

  1. The key/value store might get large and use lots of bandwidth. This is not an issue if the session is only used to authenticate a user.

  2. One relies on the client to expire/delete the cookie. Without having at least part of the session on the server one is effectively handing out a token that's valid to eternity when setting the cookie.

A follow-up question is what the natural way of implementing server side sessions in Snap would be. Ideally, I'd only want to write/modify auth and/or session backends.


Solution

  • Simplicity and minimizing dependencies. We've always taken a strong stance that the core snap framework should be DB-agnostic. If you look closely at the organization, you'll see that we carefully designed the session system with a core API that is completely backend-agnostic. Then we included a cookie backend. This provides users with workable functionality out of the gate without forcing a particular persistence system on them. It also serves as an example of how to write your own backend based on any other mechanism you choose.

    We also used the same pattern with the auth system. It's a core API that lets you use whatever backend you want. If you want to write your own backend for either of these, then look at the existing implementations and use them as a guide. The cookie backend is the only one I know of for sessions, but auth has several: the simple file-based one that is included, and the ones included in snaplet-postgresql-simple, snaplet-mysql-simple, and snaplet-persistent.