envelopmenuskypeburger-menulink-externalfacebooktwitterlinkedin2crossgithub-minilinkedin-minitwitter-miniarrow_rightarrow_leftphonegithubphone-receiverstack-overflow

akka-http-session for Java

Do you know akka-http? It is an Akka module built up on actors to expose and consume HTTP endpoints.

Since it does not support session management, some time ago we have decided to provide an extension that fills the gap and this is how akka-http-session was born.

Header image

The library provides directives allowing for client-side session management (for both mobile and web applications) by using cookies or custom headers with an optional support for JWT and/or CSRF tokens. Recently, the tool was extended with a Java API.

Code example

To illustrate a basic use case, we have implemented an example written in Java showing basics of session management.

Code snippets presented below come from the example. The complete code is available on GitHub.

Configuration

Before using the session directives, you need a session manager, which is responsible for keeping the session secure. Also a session encoder needs to be provided to encode and decode values like the session data, the max age and the server’s signature.

  new SessionManager<>(
      SessionConfig.defaultConfig(SERVER_SECRET),
      new BasicSessionEncoder<>(MySession.getSerializer())
  );

The session encoder requires a serializer, a tool that is able to serialize/deserialize the object you want to send over the wire. In our example, it is a MySession object holding a field of type String. Therefore, the SingleValueSessionSerializer converting MySession to String and vice versa will do the job just fine. If you would like to provide a custom one, simply implement SessionSerializer and use it in a session encoder.

Next thing we need to consider is the lifetime of our session. Is it one-off usage with a fixed time to live or rather a refreshable session? Answer to this question depends on your domain, project and problem you are trying to solve. For instance, if you are working on payments in a financial sector, one-off usage looks like a good choice because of security reasons (disposable session cannot be refreshed with a stolen refresh token). On the other hand an e-commerce service has different usage patterns and refreshable and long-lived session would be more suitable here.

In this example, we are going to use a refreshable session. Everytime we want to extend the lifetime of that session, we will send a refresh token. This requires us to setup a storage for these tokens on the server side:

  private static final RefreshTokenStorage<MySession> REFRESH_TOKEN_STORAGE = 
      new InMemoryRefreshTokenStorage<MySession>() {
          @Override
          public void log(String msg) {
              logger.info(msg);
          }
      };

This is a simple in-memory storage implementation available as part of akka-http-session, but a custom token storage, for example querying a relational database, can be implemented as well.

  refreshable = new Refreshable<>(getSessionManager(), REFRESH_TOKEN_STORAGE, dispatcher);

Having specified the lifecycle of the session, the last step is to choose a transport mechanism. We can choose between cookies, which are simple to use because they are automatically stored in a browser’s local storage, and headers, being more common in mobile applications, but requiring to provide a token storage. It can be set by using CookieST and HeaderST classes. The example code uses the cookie variant:

  sessionTransport = CookieST;

The sessionTransport variable is used when calling session directives in the example.

Directives

With the session manager in place, we are good to go with the Java directives provided by akka-http-session.

The example presents a simple authentication case with login/logout actions implemented. Endpoints are defined with Routes DSL. Every route is created by composing basic building blocks, i.e. directives. While akka-http provides a set of them, akka-http-session enriches it with session-related ones. The fundamental ones are:

  • setSession - creates a new session (based on configured lifetime, it can be a one-off session or a refreshable one),
  • requiredSession - asserts whether the received request comes with a session (if there is none, the request is rejected),
  • invalidateSession - invalidates a session cookie, which terminates a given session.

Session security

The session data is signed before being sent. The configuration of akka-http-session contains one mandatory parameter, which is a server secret (akka.http.session.server-secret). It should be at least 64 characters long.

With the akka.http.session.encrypt-data parameter set to true, the data is encrypted before signing. In such case, it is not readable on the client side.

Of course akka-http-session supports the secure Cookie parameter as well. During development mode it is turned off, i.e. akka.http.session.cookie.secure is set to false. However, it is strongly recommended for all sites using the HTTPS protocol to set its value to true.

Session timeout

By default, the session expires after one week. This can be adjusted to your use case by setting the akka.http.session.max-ageparameter. It specifies a number of seconds after which a session expires. You can have a non-expiring session by setting the parameter to none.

Wrap up

At the beginning, the akka-http-session add-on provided only a Scala API. Now, it also offers the Java API. Using it in your Java project became much easier and convenient.

Are you using the tool already? Let us know your impression. In case you have any idea what is missing or could be added, just tell us.