Sessions

Sessions provide a mechanism to persist data between different HTTP requests. Typical use cases include storing a logged-in user’s ID, the contents of a shopping basket, or keeping user preferences on the client. In Ktor, you can implement sessions by using cookies or custom headers, choose whether to store session data on the server or pass it to the client, sign and encrypt session data, and more.

In this topic, we’ll look at how to configure sessions, install the Sessions feature, and set the session’s content.

Session Configuration Overview

You can configure sessions in the following ways:

Install Sessions

Before installing a session, you need to create a data class for storing session data, for example:

  1. data class LoginSession(val username: String, val count: Int)

You need to create several data classes if you are going to use several sessions.

After creating the required data classes, you can install the Sessions feature by passing it to the install function in the application initialization code. Inside the install block, call the cookie or header function depending on how you want to pass data between the server and client:

  1. import io.ktor.features.*
  2. import io.ktor.sessions.*
  3. // ...
  4. fun Application.module() {
  5. install(Sessions) {
  6. cookie<LoginSession>("LOGIN_SESSION")
  7. }
  8. }

You can now set the session content, modify the session, or clear it.

Multiple Sessions

If you need several sessions in your application, you need to create a separate data class for each session. For example, you can create separate data classes for storing a user login and settings:

  1. data class LoginSession(val username: String, val count: Int)
  2. data class SettingsSession(val username: String, val settings: Settings)

You can store a username on the server in a directory storage and pass user preferences to the client.

  1. install(Sessions) {
  2. cookie<LoginSession>("LOGIN_SESSION", directorySessionStorage(File(".sessions"), cached = true))
  3. cookie<SettingsSession>("SETTINGS_SESSION")
  4. }

Note that session names should be unique.

Set Session Content

To set the session content for a specific route, use the call.sessions property. The set method allows you to create a new session instance:

  1. routing {
  2. get("/") {
  3. call.sessions.set(LoginSession(name = "John", value = 1))
  4. }
  5. }

To get the session content, you can call get receiving one of the registered session types as type parameter:

  1. routing {
  2. get("/") {
  3. val loginSession: LoginSession? = call.sessions.get<LoginSession>()
  4. }
  5. }

To modify a session, for example, to increment a counter, you need to call the copy method of the data class:

  1. val loginSession = call.sessions.get<LoginSession>() ?: LoginSession(username = "Initial", count = 0)
  2. call.sessions.set(session.copy(value = loginSession.count + 1))

When you need to clear a session for any reason (for example, when a user logs out), call the clear function:

  1. call.sessions.clear<LoginSession>()