The Auth Pattern I Copy Into Every New Project Now

Stop debating auth from scratch. This hardened pattern uses httpOnly cookies, CSRF double-submit, and TOTP 2FA. Avoid XSS and session hijacking.

domingo, 26 de julio de 2026 • 4 min read • Q2BSTUDIO Team

Por qué uso cookies httpOnly en vez de localStorage

In every new project, development teams often fall into the same debate: should we store the JWT token in localStorage or a cookie? After years of repetitive cycles, at Q2BSTUDIO we have consolidated an authentication pattern that we apply systematically, adjusting only the details each application requires (such as support for mobile clients or third-party API consumers using Bearer tokens). This pattern not only removes technical uncertainty but also closes the door to common vulnerabilities like XSS, CSRF, or session hijacking due to misconfigured CORS. In this article we share the full structure, the reasoning behind each piece, and how to migrate from an existing system without breaking anything.

The core decision: httpOnly cookie, never JS-readable storage The key of the pattern is to issue the session token in a cookie with httpOnly, Secure, and SameSite=Lax flags, scoped to a domain that works across subdomains. This cookie never touches localStorage, sessionStorage, or any JavaScript-accessible variable. The reason is straightforward: any data JavaScript can read can be extracted by an XSS payload. An httpOnly cookie is invisible to document.cookie and to any script running on the page, malicious or not. It is not a luxury; it is the difference between 'one XSS bug leaks the session' and 'one XSS bug leaks nothing session-related.' At Q2BSTUDIO, when we develop custom software, this principle is non-negotiable, as session protection is the foundation of any user-based system.

CSRF double-submit, only where needed Cookie-based authentication reintroduces the CSRF risk that a Bearer token in a header does not have (the browser attaches cookies automatically, but not custom headers). To mitigate it, we use a second JavaScript-readable cookie carrying a CSRF value, and the frontend echoes it back as a request header on every mutation. The server checks that the two match. This protection is only needed for write operations — reads do not require CSRF validation — and does not apply at all to clients that exclusively use Bearer tokens, as they were never vulnerable to this attack. In our cybersecurity projects, implementing this double verification is one of the first measures we recommend to prevent an attacker from performing actions on behalf of an authenticated user.

CORS: allowlist, never wildcard, especially with credentials The combination of Access-Control-Allow-Origin: * with credentials: true is dangerous: it allows any site to hijack your users' sessions. The solution is an explicit allowlist of origins, with credentials: true and never a wildcard or a dynamic reflection of the Origin header. At Q2BSTUDIO, when deploying infrastructure on cloud AWS/Azure, we configure services so that the CORS middleware rejects any unauthorized origin. This prevents a session-riding attack from exploiting a permissive configuration.

TOTP 2FA for any privileged role Any user with elevated permissions (admins, managers, etc.) must go through a two-factor authentication flow based on TOTP (Time-based One-Time Password). Setup, enable, and disable follow a standard process, and once activated, 2FA is required at every login. Implementing it is cheap compared to the value it brings: an extra layer that protects accounts with access to sensitive data, financial operations, or critical configurations. In environments where we integrate BI / Power BI, for example, business dashboards are often exposed to profiles that need this additional protection.

Migrating from a Bearer-token system without breaking current operation The practical part that makes this pattern adoptable in a live project is the dual-mode migration. Authentication guards accept both the httpOnly cookie and the Authorization header; CSRF checks only apply to the cookie path. The login endpoint still returns the token in the response body (for Bearer clients) while also setting the cookie. No existing integration breaks, and the frontend can migrate incrementally. We have done this in multiple Q2BSTUDIO projects, from AI platforms to systems that incorporate AI agents for process automation.

Verification checklist before calling it done In every project we check the following: (1) Login actually sets an httpOnly cookie (check response headers, not just 'it seems to work'). (2) Cookie-based requests succeed without manually attaching the token. (3) A mutation without the CSRF header gets rejected with 403, not silently allowed. (4) A request from a disallowed origin receives no Access-Control-Allow-Origin header. (5) Logout clears both cookies, not just the server-side session. Skipping any of these checks turns 'we implemented CSRF protection' into 'we implemented a CSRF header that nobody validates.'

What I would tell my past self Decide the authentication pattern once, do it well, and reuse it. Do not reopen the localStorage vs cookie debate on every new project. The CORS wildcard with credentials combination is the easiest way to accidentally build a session-hijacking vulnerability. Make it impossible to ship, not just documented as wrong. A migration plan that keeps old clients working is what actually gets a hardened pattern adopted on a live app — 'just rewrite it' proposals die in planning meetings. At Q2BSTUDIO, we apply this philosophy in every development, ensuring security is not a late add-on but a cornerstone from day one.

A BREAK?

Play for a moment before you go

OUR SERVICES

How we can help you

Do you have a project in mind?

Tell us your vision and we'll turn it into a software solution. Whatever the scope, we make your idea real.