KAHIBARO
Discord Login Register

13.6. Tokens

Why Tokens Matter in Authentication

In modern backend systems, tokens are one of the main ways to keep users logged in and to protect APIs. Instead of sending a username and password with every request, the client sends a token. The backend checks the token to decide who the user is and whether to allow the request.

Tokens are especially important for:

A token is not a password, but it acts like one for a limited time. Anyone who has a valid token can usually act as that user until it expires.

Because of this, token handling and storage must be done carefully.


Token Basics

What Is a Token?

A token is a structured piece of data, usually a string, that represents:

You can think of it like a movie ticket:

Similarly, a token:

Tokens are usually:

You will study JWTs in detail in the dedicated JSON Web Tokens chapter. Here we focus on the general idea of tokens.


Tokens vs Sessions

Both tokens and sessions try to solve the same problem: "How do we keep a user authenticated across multiple requests without sending the password every time?"

Traditional Session Based Authentication

With sessions:

  1. User logs in with username and password.
  2. Server checks credentials.
  3. Server creates a session record in a database or memory, for example:

| session_id | user_id | created_at | expires_at |
|-------------------|--------:|----------------------|----------------------|
| abc123xyz | 7 | 2026-08-27 10:00:00 | 2026-08-27 12:00:00 |

  1. Server sends a session ID to the client as a cookie.
  2. On each request, the browser sends the cookie.
  3. The server looks up the session ID in storage and finds the user.

So with sessions, the server stores the session, and the client only sends a session identifier.

Token Based Authentication

With tokens:

  1. User logs in with username and password.
  2. Server checks credentials.
  3. Server creates a token that already contains user identity and other claims, or that can be used to look up that information.
  4. Server sends the token to the client.
  5. On each request, the client sends the token, often in the Authorization header:
http
   Authorization: Bearer <token-value>
  1. The server validates the token and extracts the user information.

In many token systems, the server does not need to store anything about the token. The token itself has all the information and is verified using cryptography. JWTs are a common format for that.

Comparison

FeatureSessionsTokens
Storage locationServer side (DB, memory, cache)Client side (browser, mobile app, etc.)
What client storesSession IDEntire token
Scaling across serversNeeds shared session storeEasier, can be stateless
Revoking access earlyEasy, delete session in storeHarder if token is self contained
Typical transport methodCookiesHeaders, sometimes cookies
Ideal forTraditional web appsAPIs, SPAs, mobile apps

Sessions rely on server side state, tokens can be stateless. Stateless tokens are easier to scale horizontally, but harder to revoke before expiration.


Types of Tokens

Different kinds of tokens exist for different use cases. You will meet some of them in later chapters.

Access Tokens

An access token allows a client to access protected resources for a limited time.

Typical properties:

Example usage in an HTTP request:

http
GET /api/user/profile HTTP/1.1
Host: api.example.com
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...

You will study access tokens in detail in the "Access Tokens" chapter.

Refresh Tokens

A refresh token is used to obtain new access tokens without forcing the user to log in again.

Typical properties:

You will study them in the "Refresh Tokens" chapter.

ID Tokens

In some systems, especially with OpenID Connect, an ID token represents the user's identity and basic profile information. It is mostly used by the client and not by APIs.

Typical properties:

Opaque Tokens vs Structured Tokens

Example differences:


AspectOpaque TokenStructured Token (for example JWT)
Human readableNoPartially (header and payload)
SizeUsually shorterUsually longer (header + payload + sig)
Server storageUsually requires lookup in storeMay not require server storage
DebuggingHarderEasier to inspect during development

Token Lifecycle

A token has a life cycle from creation to expiration or revocation.

1. Issuance

Tokens are created after a successful authentication step.

Example flow:

  1. User sends credentials to /auth/login.
  2. Server verifies credentials.
  3. Server creates an access token, and maybe a refresh token.
  4. Server returns the tokens in the response.

Example response:

json
{
  "access_token": "<access-token-here>",
  "refresh_token": "<refresh-token-here>",
  "token_type": "bearer",
  "expires_in": 3600
}

The client then stores these tokens somewhere.

2. Storage on the Client

How tokens are stored depends on the client type:

Each option has security trade-offs that you will consider in security related chapters.

3. Usage

For every protected API call:

  1. Client reads the access token from its storage.
  2. Client sends it in the request, usually in the Authorization header:
http
   Authorization: Bearer <access-token>
  1. Server validates the token.
  2. If valid, server processes the request.

4. Expiration

Tokens should not live forever. Each token has:

After expiration:

Always set an expiration time for tokens. Non expiring tokens are a serious security risk.

5. Renewal

When an access token expires:

This pattern is explained in more detail in the "Refresh Tokens" chapter.

6. Revocation

Sometimes you must make a token invalid before its natural expiration time. For example:

How to revoke depends on your design:

Example approach with a version:

user_idtoken_version
73

Token payload contains token_version: 3. When you want to invalidate all existing tokens, increment token_version to 4 in the database. Any token with version 3 is rejected from that point.


Token Transport

Where Tokens Are Sent

Common transport methods:

  1. Authorization header (recommended for APIs):
http
   Authorization: Bearer <token>
  1. Cookies:
    • Token is stored as a cookie and sent automatically by the browser.
    • Can combine token based authentication with cookie properties like HttpOnly and Secure.
  2. Query parameters (generally not recommended):
    • Example: GET /api/data?access_token=<token>
    • Tokens can be logged in HTTP logs and proxies.
    • Only use when there is no other option, and be very careful.

Prefer the Authorization: Bearer <token> header for API access. Avoid sending tokens in URLs.

Example Full Request with Token

http
GET /api/orders HTTP/1.1
Host: api.shop.com
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
Accept: application/json

Server side pseudo code:

python
def get_orders(request):
    auth_header = request.headers.get("Authorization")
    user = authenticate_with_token(auth_header)
    if not user:
        return Response(status=401, body={"detail": "Invalid token"})
    orders = load_orders_for_user(user.id)
    return Response(status=200, body=orders)

Token Security Considerations

Tokens are extremely powerful, so you must treat them carefully.

Token Confidentiality

If an attacker gets a valid token, the attacker can usually act as that user until the token expires.

Basic rules:

Example of a risky log line:

python
# Bad: do not log full tokens
logger.info("Auth failed for token %s", token)

Better:

python
# Better: log a short hash or a few characters
logger.info("Auth failed for token starting with %s", token[:6])

Token Expiration and Short Lifetimes

Short lived tokens help limit damage if a token is stolen.

Example:

If an access token is stolen:

Token Scope and Permissions

Tokens should not give more permissions than necessary.

Examples:

This is sometimes called scopes or permissions:

The server must check scopes when authorizing each request.

Use the principle of least privilege. Give each token only the minimum permissions it needs.

Token Replay Attacks

A replay attack happens when an attacker captures a valid token and uses it later.

To reduce this risk:

Stateless vs Stateful Token Systems

Stateless Tokens

With stateless tokens, like self-contained JWTs:

Advantages:

Disadvantages:

Stateful Tokens

With stateful tokens:

Advantages:

Disadvantages:

In real systems, you often mix ideas:

Example: Simple Token Based Login Flow

Imagine a very simple backend that uses opaque access tokens stored in memory. This is only for understanding, not for production.

Step 1: Login and Token Issuance

Pseudo code:

python
import uuid
from datetime import datetime, timedelta
# In memory token store: token -> (user_id, expires_at)
TOKENS = {}
def login(username: str, password: str):
    user = find_user_by_username(username)
    if not user or not verify_password(password, user.hashed_password):
        raise AuthenticationError("Invalid credentials")
    token = uuid.uuid4().hex
    expires_at = datetime.utcnow() + timedelta(hours=1)
    TOKENS[token] = (user.id, expires_at)
    return {
        "access_token": token,
        "token_type": "bearer",
        "expires_in": 3600,
    }

Step 2: Using the Token to Call a Protected Endpoint

Client sends:

http
GET /api/me HTTP/1.1
Host: api.example.com
Authorization: Bearer 7d40c9f4c4d84520b3ed4cb1a657df2e

Server checks:

python
def authenticate_with_token(authorization_header: str):
    if not authorization_header:
        return None
    prefix, _, token = authorization_header.partition(" ")
    if prefix.lower() != "bearer" or not token:
        return None
    data = TOKENS.get(token)
    if not data:
        return None
    user_id, expires_at = data
    if datetime.utcnow() > expires_at:
        # Token expired, remove it
        del TOKENS[token]
        return None
    return find_user_by_id(user_id)

Endpoint:

python
def get_me(request):
    user = authenticate_with_token(request.headers.get("Authorization"))
    if not user:
        return Response(status=401, body={"detail": "Not authenticated"})
    return Response(status=200, body={"id": user.id, "username": user.username})

This example shows the core idea of tokens:

In real production systems you will:

Summary

In this chapter you learned:

Next chapters will build on these foundations and focus on specific token types like JSON Web Tokens, access tokens, refresh tokens, and protocols like OAuth 2.0 and OpenID Connect.

Views: 5

Comments

Please login to add a comment.

Don't have an account? Register now!