Skip to content

Token Storage — Complete Secure Client-Side Storage Guide

DodaTech Updated 2026-06-28 2 min read

In this tutorial, you will learn about Token Storage. We cover key concepts, practical examples, and best practices to help you master this topic.

Token storage is the practice of securely storing authentication tokens on the client side. The storage mechanism directly impacts your application's vulnerability to XSS and CSRF Attacks.

What You'll Learn

You'll learn token storage options including HttpOnly cookies, secure localStorage, and in-memory storage, with their security trade-offs.

Why It Matters

A single XSS vulnerability can steal tokens from localStorage. Improper cookie configuration enables CSRF attacks. Choosing the right storage Strategy is critical for client-side security.

Real-World Use

A banking SPA stores access tokens in memory (JavaScript variable) and refresh tokens in HttpOnly cookies. Even if an XSS attack executes, the refresh token is inaccessible to JavaScript.

flowchart TD
    A[Token Storage Options] --> B[HttpOnly Cookie]
    A --> C[localStorage]
    A --> D[Session Storage]
    A --> E[In-Memory]
    B --> F[Protected from XSS]
    B --> G[Vulnerable to CSRF]
    C --> H[Vulnerable to XSS]
    C --> I[Protected from CSRF]
    E --> J[Most Secure for Access Token]
    E --> K[Lost on Page Refresh]

Implementation

# Setting secure HttpOnly cookies from API
@app.route("/api/login", methods=["POST"])
def login():
    token = create_token(user_id)
    response = jsonify({"message": "Logged in"})
    response.set_cookie(
        "refresh_token",
        token,
        httponly=True,     # Not accessible to JavaScript
        secure=True,       # HTTPS only
        samesite="Strict", # CSRF protection
        max_age=7 * 24 * 3600,  # 7 days
        path="/api/auth"   # Scope to auth endpoints
    )
    return response

# In-memory token storage pattern (SPA)
class TokenStore:
    def __init__(self):
        self._access_token = None

    def set_tokens(self, access_token, refresh_token):
        self._access_token = access_token
        document.cookie = f"refresh_token={refresh_token}; HttpOnly; Secure; SameSite=Strict"

    def get_access_token(self):
        return self._access_token

    async function refreshAccessToken() {
        const response = await fetch('/api/auth/refresh', { credentials: 'include' });
        const data = await response.json();
        this._accessToken = data.access_token;
    }

Common Mistakes

| Mistake | Fix | |---------|-----| | Storing access tokens in localStorage | Vulnerable to XSS; use in-memory with refresh cookie | | No HttpOnly flag on cookies | JavaScript can read and steal the token | Always set HttpOnly for auth cookies | | No SameSite attribute | Vulnerable to CSRF | Set SameSite=Strict or Lax | | cookie without Secure flag | Token sent over HTTP | Always set Secure=true | | Overly broad cookie path | Token sent to every endpoint | Restrict path to /api/auth |

What's Next

Learn about auth middleware patterns for consistent token validation.

Built by the developers of DodaTech

Doda Browser, DodaZIP & Durga Antivirus Pro