About this article
As the seventh installment of the âFrontend Architectureâ category in the series âArchitecture Crash Course for the Generative-AI Era,â this article explains frontend-side authentication and authorization.
The frontend runs in the userâs hands - and the attackerâs hands. We treat browser-specific defenses on the premise that F12 can peek into and rewrite every variable. This article covers XSS/CSRF defenses, Cookie attributes, CSP, token storage locations, and refresh strategies, while leaving authentication methods (MFA, Passkey, IDaaS selection) to the security chapter and session implementation to the software chapter.
What is frontend auth design in the first place
Frontend auth design is, roughly speaking, âdeciding how to safely handle user credentials inside the browser â an environment in the enemyâs hands.â
Imagine a glass safe. The contents are fully visible and the keyhole is exposed â thatâs the browser environment. Opening F12 (DevTools) lets you peek at every variable and Cookie. Designing âwhere to store tokensâ and âhow to build a mechanism that canât be stolen via XSSâ under this premise is frontend auth design.
Why frontend auth design is needed
The browser runs âin the enemyâs handsâ
Server-side code is accessible only to administrators, but browser JavaScript is fully visible and modifiable via F12. A design that ignores this premise renders all authentication meaningless.
Wrong token-storage choice becomes instant vulnerability
Put JWT in localStorage and itâs stolen by XSS; mis-set Cookie attributes and itâs exploited by CSRF â the choice of storage location and attributes directly determines the security level.
Must align with server-side auth design
Authentication doesnât complete on the frontend alone. Without designing it as a pair with the backendâs auth and session design, one sideâs defenses become meaningless.
This articleâs coverage
| Article | Coverage |
|---|---|
| This article (frontend auth) | F12-premised authorization UI / Cookie attributes / XSS / CSRF / CSP / token storage |
| 50/01 Auth design | Auth strength / MFA / Passkey / IDaaS / SSO strategy |
| 50/02 Authorization and IAM | Design of RBAC / ABAC / ReBAC |
| 20/07 Authentication and sessions | Server session vs JWT / OAuth implementation |
This article does not cover âMFA factor selection,â âIDaaS selection,â or âauthorization model details.â What the frontend should do is decide what to defend in the hostile territory called the browser.
The question of this article is âwhat can you do on the premise that F12 can rewrite anything?â Authentication methods themselves are handled in another chapter.
The frontend is âan ultimately untrusted environmentâ
Frontend authorization checks are just UI decoration. UX control like showing/hiding the admin button is fine in the frontend, but real security checks must always happen on the server side. The moment you bend this principle, auth design collapses.
I had an experience as a junior - thinking my design that checked role === 'admin' only on the frontend was âfine because it doesnât show the admin screenâ - shattered in one shot by a senior saying âopen F12 and you can see everything.â Hitting the limits of frontend authorization usually happens after taking this kind of hit.
Frontend authorization is just for UI conditional rendering. The real lock goes on the server - thatâs the rule.
Four authentication choices
From the frontendâs perspective, there are essentially only 4 patterns. âSPA so JWTâ is an old 2010s indoctrination - the modern standard is Cookie + BFF.
| Method | Detail |
|---|---|
| Server session (Cookie) | Same-domain standard, simplest |
| JWT in localStorage | Landmine - one XSS leaks everyoneâs tokens |
| JWT in httpOnly Cookie | Hybrid, the realistic top choice |
| OAuth/OIDC delegation | External platforms like Auth0 / Cognito / Firebase Auth |
âSPA so put JWT in localStorageâ is a trap still mass-produced by old sources. If even one XSS gets through, all usersâ tokens are taken. Even when using JWTs, put them in âhttpOnly Cookie.â Raw localStorage operation is synonymous with accidents.
âSPA = JWT in localStorageâ is a finished design. Cookie + BFF is the modern first choice.
Login flow (Authorization Code + PKCE)
Authorization Code + PKCE is the standard login flow for modern SPAs. Third-party auth from Google, Apple, GitHub, etc. all adopt the same shape. PKCE (Proof Key for Code Exchange, an extra check to prevent code interception) is an additional verification step to crush âcode-interception attacksâ on public clients.
1. User â redirect to auth server (with code_challenge)
2. After login, code is returned
3. Get tokens with code + PKCE verifier
4. BFF verifies and issues a Session Cookie
5. Subsequent API calls use the Cookie
PKCEâs idea is simple: the client makes a random verifier and passes its hash (challenge) on the first request. Later, when exchanging the code for tokens, the original verifier must be presented. Even if the code is stolen mid-flight, an attacker without the verifier canât use it. Required for public clients like mobile and SPAs.
Authorization Code with PKCE - the only choice. Never use the old Implicit Flow.
Cookie attribute design
For Cookie-based auth, attribute settings literally decide security. They look mundane, but missing one creates a critical XSS-Cookie-leak vulnerability.
| Attribute | Meaning |
|---|---|
| HttpOnly | Cannot be read from JS (most important XSS countermeasure) |
| Secure | Sent only over HTTPS |
| SameSite=Lax | Default safe value, CSRF countermeasure |
| SameSite=Strict | Full CSRF prevention (UX impact) |
| Domain | Specified when sharing across subdomains |
| Path | Limits the path it applies to |
The modern minimum line is the triad of HttpOnly + Secure + SameSite=Lax. This single set blocks Cookie reading via XSS, eavesdropping over HTTP, and accidental cross-site sending.
Forgetting one attribute and itâs over. Putting it on a checklist and checking mechanically is the rule.
XSS and CSRF
The two big threats facing the frontend are XSS and CSRF. Theyâre different things, but each collapses an auth system in one shot. Always design countermeasures as a set.
flowchart TB
XSS["XSS<br/>Cross-Site Scripting<br/>malicious JS runs on the page"]
CSRF["CSRF<br/>Cross-Site Request Forgery<br/>authenticated request fired from another site"]
XSS_M1[CSP<br/>narrow allowed sources via script-src]
XSS_M2[Escaping<br/>leave to template engine]
XSS_M3[HttpOnly Cookie<br/>unreadable from JS]
CSRF_M1[SameSite Cookie<br/>Lax/Strict]
CSRF_M2[CSRF token<br/>required for POST requests]
XSS --> XSS_M1
XSS --> XSS_M2
XSS --> XSS_M3
CSRF --> CSRF_M1
CSRF --> CSRF_M2
XSS -.|if XSS gets through<br/>other defenses are nullified|.-> CSRF
classDef threat fill:#fee2e2,stroke:#dc2626,stroke-width:2px;
classDef defense fill:#dbeafe,stroke:#2563eb;
class XSS,CSRF threat;
class XSS_M1,XSS_M2,XSS_M3,CSRF_M1,CSRF_M2 defense;
| Attack | Content | Countermeasure |
|---|---|---|
| XSS (Cross-Site Scripting) | Inject malicious JS into the page | CSP / escaping / HttpOnly Cookie |
| CSRF (Cross-Site Request Forgery) | Fire authenticated requests from another site | SameSite Cookie / CSRF token |
The moment XSS gets through, auth is effectively void. Once attackers can run JS, all info except Cookies is taken, and APIs can be hit while impersonating the user. So frontend security goes XSS countermeasures first, CSRF second - in that order.
The moment XSS is allowed, youâve lost. Other countermeasures collapse from a broken premise.
CSP (Content Security Policy)
CSP (Content Security Policy, an HTTP header that declares allowed resource sources to the browser) is a mechanism for declaring to the browser âthe allowed sources of scripts, styles, and images on this page.â Itâs the trump card of XSS countermeasures - just the setting âno inline scriptsâ neutralizes most XSS attacks.
Content-Security-Policy:
default-src 'self';
script-src 'self' https://trusted.cdn.com;
style-src 'self' 'unsafe-inline';
object-src 'none';
Banning inline scripts is a powerful move that wholesale invalidates injections like <script>alert('xss')</script>, but applying it suddenly to existing pages breaks the site - so phase it in. Next.js and Astro auto-inject CSP nonces, so the entry barrier dropped a lot from the modern-FW side.
CSP is the heart of XSS countermeasures. With a modern FW thereâs no reason not to introduce it.
Authorization UI in the frontend
Authorization in the frontend centers on UI conditional rendering like âshow/hide admin button.â This is a UX matter, not security - hiding the screen and actual permission control are different things.
{user.role === 'admin' && <AdminPanel />}
This stops the admin features from rendering, but an attacker can rewrite the condition to true in F12 and display AdminPanel. At that point, the admin API must not be callable - so permission checks must always exist on the API side.
Design principles:
- Data returned by APIs is permission-filtered
- Page-transition guards (router middleware) are auxiliary
- Donât even fetch info you donât want shown
Authorization model design (RBAC / ABAC / ReBAC) is consolidated in the security chapter because it isnât frontend-specific. What the frontend side of this article should grasp is the principle: âno matter which authorization model you adopt, doing the permission check on the frontend collapses the design.â
Frontend authorization is UX decoration. Real security always sits on the server.
Token storage
Where you place auth tokens makes a vast difference in security level. The modern standard is httpOnly Cookie as the base, used together with memory.
| Location | Safety | Notes |
|---|---|---|
| httpOnly Cookie | Excellent | Unreadable from JS, doesnât leak via XSS |
| Memory (Redux / variables) | Good | Disappears on reload |
| sessionStorage | Marginal | Cleared on tab close, but XSS-vulnerable |
| localStorage | Bad | Avoid - one XSS leaks everyoneâs tokens |
The recommended composition is âshort-lived Access Token in memory, long-lived Refresh Token in httpOnly Cookie.â The memory side auto-clears on reload; the Cookie side is shielded by httpOnly - a two-layer defense stands up.
Refresh token strategy
Splitting Access Token and Refresh Token is the modern standard pattern for session management. Hit daily APIs with the short-lived Access Token, and refresh with the long-lived Refresh Token when it expires.
1. Access Token (15 min) expires
2. Client sends Refresh Token (30 days, Cookie)
3. BFF issues a new Access Token
4. Optionally rotate the Refresh Token (re-issue)
Refresh Token Rotation is a mechanism that issues a new Refresh Token each time itâs used, immediately invalidating the old one. If the old token is reused, itâs detected as stolen and the entire session is revoked. Auth0 and Firebase Auth support this natively, and adding it raises safety one rank.
Refresh Token Rotation + httpOnly Cookie is the modern recommended composition.
Logout and revocation
Logout tends to be taken lightly, but itâs quietly central to security. Just âdelete Cookie when button clickedâ isnât enough - the server must also revoke the Refresh Token.
| Item | Design |
|---|---|
| Logout | Delete Cookie + revoke Refresh Token on server |
| All-device logout | Discard all of the userâs Refresh Tokens |
| After password change | All sessions auto-revoke |
| On suspicious-behavior detection | Admin can force-revoke |
âAll-device logoutâ is for emergency stops in case of theft or loss, and is required for high-importance services. The accident âlogged out but old tab still worksâ is a direct line to incident.
Authorâs note - cases where âlooking-defended-onlyâ collapsed
In 2022, it was reported that Slack had some employee tokens stored on GitHub stolen, and through those tokens, parts of internal private repos were accessed. The mechanism itself was âgeneral token-based auth,â and the code worked correctly. Even so, it was breached due to laxness in storage location and revocation operations - a story still talked about today.
In the same 2022, there was also the report that a Sitel device entrusted with Okta support work was breached, and the LAPSUS$ group reached the level of taking screenshots of Oktaâs internal screens. The very source of SSO - the auth platform - was shaken via a contractorâs terminal.
Iâve seen with my own eyes in past projects the structure where âthe code is perfect, but breached through operational gaps,â and from then on Iâve thought of these stories as not someone elseâs problem. All of them happen in situations where âthe frontend code is cleanâ and âthe protocols are standard.â Authentication is something defended by both wheels of code-correctness and operational-correctness; cases that drove home, even from the outside, the fact that one wheel alone leaves holes.
Authentication is both wheels of code and operations. With one alone, holes always remain.
Auth setting numerical gates and Cookie-attribute checks
Note: Industry baseline values as of April 2026. Will become outdated as technology and the talent market shift, so requires periodic updates.
Leaving the âcorrect defaultsâ vague in frontend auth always opens holes. Below are the modern Web standard values.
| Setting | Recommended | Reason |
|---|---|---|
| Access Token expiry | 15 minutes | Minimize damage on leak |
| Refresh Token expiry | 14-30 days | Balance with UX |
| Refresh Token Rotation | Enable | Detects theft, revokes all sessions |
| Cookie HttpOnly | Required | Cannot be read by XSS |
| Cookie Secure | Required | HTTPS-only |
| Cookie SameSite | Lax (minimum) or Strict | CSRF countermeasure |
CSP script-src | âselfâ + nonce | Inline forbidden |
| Lighthouse Best Practices | 100 | Comprehensive security basics |
| Auth-failure rate limit | 5 attempts / 15 min | Brute-force countermeasure |
| Passkey support | Required to consider from 2026 | Standard SMS-MFA replacement |
âHttpOnly / Secure / SameSite=Laxâ as a triad is the minimum line for Cookies. Missing even one is out of the question - itâs a basic check verifiable instantly in Chrome DevTools.
Forgetting one attribute and itâs over. Verify mechanically with a checklist.
Frontend auth pitfalls and forbidden moves
Here are the typical accidents in frontend auth. All of them are direct causes of all-user leaks, impersonation, and session hijacking.
| Forbidden move | Why itâs bad |
|---|---|
| Store JWT in localStorage | Landmine - one XSS leaks everyoneâs tokens. The trap of old 2010s sources |
Branch only on user.role === 'admin' in the frontend | F12 can rewrite to true. Server-side authorization is required |
| Newly implement OAuth Implicit Flow | Deprecated from 2020 onward. Authorization Code with PKCE is required |
| Without PKCE for Authorization Code | On public clients, code interception finishes you |
| Forget HttpOnly | Cookies become readable by XSS. An attribute miss is an instant accident |
| SameSite as None without Secure | CSRF passes through. SameSite=Lax is the default safe value |
Leave unsafe-inline in CSP | CSP introduction is meaningless. Doesnât function as XSS countermeasure |
| Logout that only deletes the Cookie | Server-side Refresh Token survives. Revocation API is required |
| Password reset with predictable tokens | Brute-forceable. 128-bit entropy + 15-min TTL |
| Rely on SMS MFA only | Broken by SIM-swap fraud. TOTP / Passkey required |
| Self-implement auth | Becomes hole-ridden. Delegate to Clerk / Auth.js / Auth0 |
| Skipping CSP as âitâs for big sites, not mineâ | Next.js/Astro have auto nonce-injection. Abandoning the XSS-countermeasure baseline |
| Not enabling Refresh Token Rotation | Theft detection doesnât work; canât revoke all sessions on leak |
The 2022 Okta breach (366 customers affected via Lapsus$), the 2022 LastPass leak (encrypted vault copies leaked), the 2023 Cloudflare-via-Okta intrusion â the reality that even security specialists are breached. Monitoring âthe delegation targetâs MFA, audit logs, and least privilegeâ on the operational side is essential.
For authentication: donât write it, borrow it, and watch it. Never miss one of the three.
AI decision axes
| Favored in the AI era | Disfavored in the AI era |
|---|---|
| External delegation like Clerk / Auth.js / NextAuth | Self-implemented Cookie sessions |
| Standard protocols like Passkey / OIDC | Custom auth-token designs |
| httpOnly Cookie via BFF operations | Storing JWT in localStorage |
| Explicit CSP, HttpOnly, etc. in code | Settings left to defaults |
- Delegate to external auth platforms (Clerk / Auth.js / Auth0 / Firebase Auth)
- httpOnly Cookie + BFF as base composition (localStorage forbidden)
- Authorization always on the server side (frontend only does UI conditional rendering)
- Passkey + OIDC standard protocols (avoid custom designs)
What to decide - what is your projectâs answer?
For each of the following, try to articulate your projectâs answer in 1-2 sentences. Starting work with these vague always invites later questions like âwhy did we decide this again?â
- Auth method (Cookie / JWT / external delegation)
- Auth platform (self-built / Auth0 / Cognito / Firebase Auth / Clerk)
- Cookie attribute settings (HttpOnly / Secure / SameSite)
- Mandatory MFA (admins only / all users)
- Timing of Passkey support
- SSO support (SAML / OIDC)
- Authorization model (RBAC / ABAC / ReBAC)
- Session timeout and refresh strategy
Summary
This article covered frontend auth, including browser-premised XSS/CSRF defenses, Cookie attributes, CSP, token storage, Refresh Token Rotation, and external-platform delegation.
Identify whatâs defendable on the F12 premise, place httpOnly Cookie + BFF as the base, and delegate authentication to external platforms. That is the practical answer for frontend auth in 2026.
Next time weâll cover SEO (search engine optimization, OGP, sitemap, structured data).
I hope youâll read the next article as well.
đ Series: Architecture Crash Course for the Generative-AI Era (37/89)