Session Token in Application Development — What It Is, How It Works, and Differences from JWT

Author: IT Sectr Published: 2026-04-05 Reading time: 9 min

Session Token is a unique identifier that the server creates after successful user authentication and uses to identify subsequent requests. Unlike self-contained tokens (JWT), a session token is a random string that does not contain data by itself: all session information is stored on the server in RAM or a database. According to OAuth.com, 2025, the session token remains the most common authentication mechanism in server-side web applications and hybrid mobile architectures.

Key Takeaways

  • Session Token — a random identifier referencing server-side session data
  • Stateful — the server stores session state in Redis, Memcached, or a database
  • Easy Revocation — simply delete the session record on the server, and the token becomes invalid
  • Security — data is not stored in the token, eliminating leakage through decoding
  • Cookie — the traditional way to pass a session token in web applications with HttpOnly, Secure, and SameSite flags

What Is a Session Token?

Session Token (session identifier) is a unique string that the server generates and associates with session data after user authentication. The token does not contain any user information — it is simply a key to the data stored on the server. This approach is called stateful authentication: the server stores the state of each active session and verifies it on every request.

Session data includes: user ID, login time, IP address, user-agent, permission list, last activity time. When the client sends a request with a session token, the server finds the corresponding record in the session store, checks its validity, and retrieves the data to process the request. If the session record is missing or has expired, the server returns an authentication error and requires re-login.

According to OWASP, 2025, the session token remains the standard for applications requiring immediate access revocation — for example, in banking systems and corporate portals where an administrator must be able to terminate a user session instantly. In such systems, the session token provides full control over access that is unattainable for stateless tokens without additional blocking mechanisms.

How Does a Session Token Work

The process begins when the client sends credentials to the authentication server. The server verifies the login and password, creates a session record in the store (usually Redis or a database), and returns a unique session token to the client. The client saves the token and sends it with every subsequent request, and the server checks the session existence and validity each time.

Server Session and Storage

Redis is the most popular session store thanks to in-memory storage and TTL (time-to-live) support. Each session is stored as a key-value pair, where the key is the session token and the value is a JSON object with session data. TTL automatically removes expired sessions. Alternatives: Memcached (memory only, no disk persistence), PostgreSQL/MySQL (persistent but slower), and DynamoDB (for AWS infrastructure).

Example of a session structure in Redis: session:{token}{“userId”: 42, “role”: “admin”, “createdAt”: 1812345678, “lastAccess”: 1812345678}. The server updates lastAccess on each request, which allows implementing an inactivity timeout — automatic session termination after a period of inactivity.

Cookie vs Header

Session Token can be transmitted in two ways: via HTTP cookie or via the Authorization HTTP header. Cookies are the traditional method for web applications: the server sets a cookie with HttpOnly (inaccessible to JavaScript), Secure (HTTPS only), and SameSite (CSRF protection) flags. For mobile applications, the Authorization: Bearer <session_token> header is more commonly used, since the cookie mechanism is not always convenient in native clients.

Session Token Lifecycle

The lifecycle of a session token includes three stages: creation, maintaining an active session, and termination. Each stage requires proper security configuration to prevent token leakage or interception.

Creation, Storage, and Deletion

Creation — the server generates a cryptographically strong random string of 128–256 bits (for example, via SecureRandom in Java or os.urandom in Python). The token must be unpredictable — using UUID or timestamp without entropy is unacceptable. Storage on the client: on iOS — Keychain, on Android — EncryptedSharedPreferences, on the web — HttpOnly cookie. Deletion occurs on logout: the client removes the token from storage, the server deletes the session record from Redis. After logout, the session token becomes useless — the server will not find a corresponding record.

According to SANS Institute, 2025, proper implementation of session termination (logout with server-side cleanup) prevents up to 70% of attacks using stolen tokens. It is critical not just to delete the token on the client side, but also to invalidate the session on the server.

Session Token vs JWT

Session Token and JWT represent two different approaches to authentication. Session Token is stateful (the server stores the state), JWT is stateless (data inside the token). The choice between them depends on the application architecture and security requirements.

CriterionSession TokenJWT
ModelStateful (data on server)Stateless (data in token)
RevocationInstant — delete session from RedisRequires blacklist or short TTL
Size16–64 bytes500–2000 bytes
Data StorageServer only (secure)Inside token (base64, not encrypted)
ScalingRequires shared storage (Redis)Not required — token validated locally
CSRF ProtectionRequires SameSite cookie + CSRF tokenNot required (token in header)

When to Choose Session Token

Session Token is preferable when: instant session revocation is required (banking, admin panels), the application runs on one or several servers with a shared Redis, session data is large and does not fit in JWT, or the team wants to minimize the risk of data leakage through token decoding. In such scenarios, the session token provides immediate access blocking upon suspicious activity — just delete one record from Redis, and all user sessions become invalid.

According to Redis, 2025, using TTL at the session key level (EXPIRE command) automatically clears expired sessions without overhead on background tasks. For sessions with a TTL of 1 hour and a load of 10,000 concurrent users, Redis consumes about 1 GB of RAM with a session size of 1 KB, making it cost-effective for most applications.

Session Token Security

Security of session tokens is based on two principles: the token must be unpredictable and protected during transmission and storage. The main threats are token interception (man-in-the-middle, XSS), token prediction (weak generation), and session fixation.

Protection Against Token Theft

Protection includes: using HTTPS for all requests with a token, setting a short session TTL (15–60 minutes of inactivity), binding the session to IP and user-agent (additional verification on each request), using Secure and HttpOnly flags for cookies, and regular rotation of the session token after sensitive operations (password change, privilege escalation). OWASP also recommends implementing Session Management with invalidation of the old session when creating a new one after login — this prevents session fixation.

According to OWASP ASVS, 2025, a session must be bound to at least two factors: the token itself (what the client has) and IP/user-agent (what the server knows). If these factors do not match, the server should terminate the session and require re-authentication.

Example Implementation in Kotlin

Below is an example of a server-side session token implementation in Kotlin using Spring Boot and Redis. The server generates a cryptographically strong token via SecureRandom, saves the session in Redis with TTL, and verifies it on each request. The code demonstrates three main operations: session creation, validation, and invalidation.

kotlin
data class Session(
    val userId: Long,
    val role: String,
    val createdAt: Long,
    val lastAccess: Long
)

object SessionManager {
    private val redis = JedisPool("localhost", 6379)

    fun createSession(userId: Long, role: String): String {
        val token = generateSecureToken()
        val session = Session(userId, role, now(), now())
        redis.resource.use { conn ->
            conn.setex("session:$token", 3600, toJson(session))
        }
        return token
    }

    fun validateSession(token: String): Session? {
        redis.resource.use { conn ->
            val json = conn.get("session:$token") ?: return null
            return fromJson(json)
        }
    }

    fun invalidateSession(token: String) {
        redis.resource.use { it.del("session:$token") }
    }

    private fun generateSecureToken(): String {
        val bytes = ByteArray(32)
        SecureRandom().nextBytes(bytes)
        return Base64.getUrlEncoder().withoutPadding().encodeToString(bytes)
    }
}

This implementation uses JedisPool for thread-safe connection to Redis. The createSession method sets a TTL of 1 hour (3600 seconds) — after this period Redis will automatically delete the record. The validateSession method returns null for non-existent or expired sessions, allowing the server to correctly handle a request with an invalid token and return HTTP 401.

Frequently Asked Questions

How does a session token differ from an access token?

Session token is a server-side session identifier (stateful). An access token is credentials for API access (can be JWT or opaque). Session tokens are typically used for web sessions, while access tokens are used for API requests in mobile and SPA applications. They can coexist: session token for the web, access token for the API.

How to protect a session token from XSS attacks?

The main protection is setting the HttpOnly flag on the cookie containing the session token. This flag prevents JavaScript from accessing the cookie, making XSS attacks useless for stealing the token. Additionally, the SameSite=Strict flag prevents the cookie from being sent with cross-site requests, protecting against CSRF.

How long should a session token live?

Two timeouts are recommended: an absolute timeout (8–24 hours — maximum session lifetime) and a relative timeout (15–30 minutes of inactivity — after which the session ends). For banking applications, the absolute timeout is reduced to 1–2 hours; for email clients, it can reach 7 days.

What is session fixation?

Session fixation is an attack where an attacker forces a user to use a known session identifier. Protection: after successful authentication, the server must create a new session token rather than continue using the one passed by the client. The old token must be invalidated regardless of its origin.

Can a session token be used in REST API?

Yes, a session token is suitable for REST API if the client sends it in the Authorization header (not a cookie). For mobile applications, this is a common practice. The downside: when scaling to multiple servers, a shared session store (Redis) is required, which adds a single point of failure to the architecture.

Summary

  • Session Token — a stateful identifier referencing server-side session data
  • Advantage — instant revocation and full control over sessions on the server
  • Storage — Redis, Memcached, or database with TTL for automatic cleanup
  • Security — SecureRandom generation, HTTPS, HttpOnly + SameSite cookies
  • Session vs JWT — Session is easier to revoke, JWT is easier to scale
  • Timeouts — absolute (8–24h) and relative (15–30 min of inactivity)
  • Session fixation — prevented by creating a new token after login

We will develop a mobile application turnkey

IT Sectr creates iOS and Android applications for startups and businesses since 2017. We will advise you and propose the best solution.

Discuss the project

Read also