DEV Community

Abdessamad MOUHASSINE
Abdessamad MOUHASSINE

Posted on • Edited on

From Scratch: Web Sessions

Hello folks,

As a first contribution, I want to share with you my thoughts about web sessions. Let's start by defining what are server-side sessions ? then I will show you an example of an abstract class that manages sessions in a simple and elegant way.

Web sessions is an industry standard feature, that allows server applications to maintain and store user-specific data, during multiple request/response interactions between the client application, mainly the browser, and the server.

State management is the main purpose of web sessions, they have no relationship with cookies, requests, responses, programming language or framework. They all share the same members and behavior and could be written in any language.

Properties

The basic, and required, session properties could be:

  • A state which is the main attribute in the session class. it can be a simple Map object that holds the key/value pairs.
  • A unique identifier or token to distinguish a session from another.
  • A lifetime, or time to live (aka TTL) property to calculate an expiry time after a moment of inactivity. it correspond to the number of seconds a session can live before expiration.
  • Finally, a storage, or whatever property name, to store a persistence adapter. It will be responsible of saving and retrieving the session's data from the storage (a text file in the file system, a database or the internal memory of the program executing the application).

Methods

In object oriented programming, both members and methods reside in the same class. To be autonomous, a session instance have to:

  • save its state for further use,
  • destroy the data if the session is expired,
  • retrieve the state from storage on initialization,
  • and regenerate a new identifier when it's necessary.

So, our session class can have the below structure:

abstract class Session {
  /**
   * A Map object to store key/value pairs
   */
  private state: Map

  /**
   * A string that uniquely identifies the session
   */
  private id: string

  /**
   * A number of seconds, milliseconds or even minutes to get the expiry time
   */
  private lifetime: number

  /**
   * Storage driver is responsible of the saving/retrieving the session state
   */
  private storage: StorageInterface


  /**
   * Start the session, loading the state from the storage
   */
  public async start (): boolean

  /**
   * End the session, saving the state in the storage
   */
  public async commit (): boolean

  /**
   * Regenerate a new session ID, maintaining the current state
   */
  public async regenerate (): boolean

  /**
   * Invalidate the session, removing or flagging the session as expired
   */
  public async invalidate (): boolean
}

Methods like get(), set() and remove() ... etc, are necessary to manipulate the session state, but we'll ignore them for simplicity.

I've used TypeScript notation for the code example, and wrote a full implementation on Github, if you would like see it in action.

Storage

The persistence driver, that encapsulates the storage, is also thin and optimized. It has one, and only one, responsibility: Persistence.

interface StorageInterface {
  /**
   * Retrieve an entry by its key
   */
  read (key: string): any

  /**
   * Remove an entry by its key
   */
  remove (key: string): any

  /**
   * Save an entry's data for the given time
   */
  write (key: string, data: any, ttl: number): any
}

Wrapping up

This is the general concept of web sessions and their reason to exist. They offer the functionality (state management) not the usability (creation, transfer, encoding, or persistence).

The Decorator design pattern can be used to add more features to sessions without the need to modify or rewrite it from scratch. Unfortunately, web framework developers, repeat themselves, and re-implement the same session logic, over and over, with a different API.


Links

Top comments (0)