← All writing
Backend

Auth for Client Projects: JWT Cookies Without the Drama

LocalStorage tokens, refresh-token choreography, third-party auth platforms — most small applications need none of it. An httpOnly cookie and bcrypt cover the real requirement.

Authentication is where small projects most often import big-company complexity. Before reaching for an auth platform or a refresh-token dance, it is worth stating the actual requirement of a typical client build: an admin signs in, stays signed in for a while, and nobody else gets in.

The shape that works

  • Passwords hashed with bcrypt — never stored, never logged.
  • On login, sign a JWT with a server-side secret and a sensible expiry.
  • Deliver it in an httpOnly, SameSite=Lax cookie — JavaScript cannot read it, so a stray XSS cannot exfiltrate it, and the browser sends it automatically.
  • Protected API routes verify the token and check the role. That's the whole middleware.

Why not localStorage?

Because any script that runs on your page — including the compromised analytics snippet you pasted in 2024 — can read localStorage. The httpOnly cookie removes that entire class of theft in exchange for one CSRF consideration, which SameSite=Lax plus JSON-only endpoints largely settles for same-origin apps.

What I deliberately skip on small builds

  • Refresh tokens — a 7-day expiry and a login page cost less than the choreography.
  • Session stores — statelessness keeps single-server deploys simple; add Redis when you actually have two servers.
  • Auth SaaS — worth it for social login and orgs; overkill for one admin panel.
Security budgets are real. Spend yours on the hash, the cookie flags, and HTTPS — not on architecture you won't operate.

Scale changes these answers. But scale is a good problem, and you will see it coming.

#auth#jwt#security#cookies
AA
Written byAmanat Ali

A full-stack developer who builds websites end-to-end — Next.js, Node.js, and MongoDB — and writes buildlog in the margins.