Module io.inverno.mod.session


module io.inverno.mod.session

The Inverno framework session module provides general support to manage session in an application.

A session is typically used to store information for a client accessing the application and make them available between requests. It is identified by a unique session id generated by the application and passed to the client which must provide it on each request to the application so it can resolve back the session.

A session is temporary and its data volatile, it has to be set to expire either after a specific period of inactivity or at a specific time in the future.

The session API defines the general Session interface for managing a session and its data in an application and the general SessionStore interface for specifying a session persistence layer. The SessionIdGenerator interface is used to define strategies for generating unique session identifier.

JWTSession, JWTSessionStore and JWTSessionIdGenerator extends above general API to support stateless session data embedded in a JWT used as session identifier and as a result stored on the client side. Sessions are not fully stateless as they are still tacked in a session store and as such can be expired or invalidated independently of the token.

The module provides the following session store implementations:

  • InMemoryBasicSessionStore which stores session in a concurrent map in memory using opaque session identifiers.
  • RedisBasicSessionStore which stores session in a Redis data store using opaque session identifiers.
  • InMemoryJWTSessionStore which stores session in a concurrent map in memory using JWT session identifiers which may contain stateless session data.
  • RedisJWTSessionStore which stores session in a Redis data store using JWT session identifiers which may contain stateless session data.

The following shows how a basic session can be created, resolved and used in an application:


 public class SomeService {

     public static class SessionData {
         AtomicInteger counter;
     }

     private final SessionStore<SessionData, Session<SessionData>> sessionStore;

     public SomeService(SessionStore<SessionData, Session<SessionData>> sessionStore) {
         this.sessionStore = sessionStore;
     }

     public void someAction(String sessionId) {
         Mono.justOrEmpty(sessionId)
             .flatMap(this.sessionStore::get)
             .switchIfEmpty(sessionStore.create())
             .flatMap(session -> session.getData()
                 .doOnNext(sessionData -> System.out.println("This is request #" + sessionData.counter.incrementAndGet()))
                 .then(session.save())
             );
     }
 }
 
Since:
1.13
Author:
Jeremy Kuhn