A while ago in a technical interview I got asked:
“Can you walk me through how authentication and authorization actually work under the hood?”
...
For further actions, you may consider blocking this person and/or reporting abuse
Great article, thanks Sylwia Laskowska! 🙌
Your breakdown of ID tokens vs Access tokens vs Refresh tokens is super clear and actionable:
localStorageorsessionStorageis a risky move—XSS wins too easily. (DEV Community)One question though: when you say the Access token lives just in memory, how do you manage safe page refreshes or tab closes in single-page apps without hurting UX? Would love a few mini patterns if you plan a part 2.
Looking forward to part 2 and digging into PKCE + BFF flows!
Managing access tokens purely in memory definitely introduces UX challenges with page refreshes and tab closes in SPAs. As Sylwia hinted, common patterns to handle this include implementing silent refresh mechanisms where a hidden iframe or background request fetches a new access token using the refresh token stored securely in an HttpOnly cookie. Another solid approach is the Backend-for-Frontend (BFF) pattern, where tokens never hit the browser but sessions are managed server-side, effectively eliminating client-side token storage risks while maintaining seamless UX.
That's an excellent and spot-on summary!
You've perfectly captured the two most robust and widely adopted strategies for solving the in-memory token storage dilemma in SPAs.
Silent Refresh (using an HttpOnly Refresh Token cookie) provides the balance of security and seamless UX.
The BFF Pattern offers the highest security baseline by eliminating client-side token exposure entirely.
Thanks for enriching the discussion!
If sessions are managed server side you don't need tokens at all. You're just stateful at that point
Absolutely — 100% agreed 👍
Once you move to a BFF or any server-side session model, you’re no longer doing “token-based auth” in the browser — the session is the auth, and the browser just carries a session cookie.
The moment you go stateful, the whole “where do I store the access token” problem disappears entirely.
I’m planning to touch on this contrast in Part 2 as well — because a lot of SPA devs don’t realise “no tokens on the client” is actually a valid (and often superior) option. 🚀
Thanks so much 🙌 really glad the breakdown clicked!
Re: access token + page refresh — that’s exactly the topic I start with in Part 2, because that’s where the “in-memory” strategy meets real UX 🙂
Different ways to survive a reload (silent refresh / BFF etc.) will be covered there.
Part 2 is coming next 🚀
This is such a clear and fun read, Sylwia! The passport/visa analogy nailed it 😂
Totally agree on avoiding localStorage — I’ve seen so many early-stage apps trip on that one.
Excited for Part 2 and the PKCE section 👏
Authentication is like showing your passport to prove who you are, while authorization is like the visa that grants you permission to enter certain places. In tech terms, the ID token verifies your identity for the frontend, and the access token grants your app permission to call APIs. This mental model helps build secure and clear authentication flows that align perfectly with the blog’s explanation.
Ahh thank you! 😄
So glad the border/passport analogy landed — it’s my favorite way to make sense of all the token chaos 😂
And yes, localStorage is like leaving your passport at the café — looks fine until it’s not.
Great article, thank you!
I have a question.
Where should I store access token and refresh token in react based server or any html, without backend?
If I store access token and refresh token in sessionStorage, it will be blown away, but I want to keep them, so when user reopens it, the login status is still remained.
Thanks! 🙌
Access token should live in memory, and the refresh token should be stored as an HttpOnly cookie set by the IdP, not in local/sessionStorage.
On page load, the app just does a silent refresh using that cookie to get a new access token — that’s how login survives a reopen without storing tokens in JS storage.
I’ll cover this step-by-step in the next article (Part 2) 🚀
I look forward to it.
Just a couple of questions are wandering in my mind.
So in this case, http cookie should be set by the server. But if the backend server has a different domain, how can I set the cookie for client?
Client domain A.com, server domain B.com. And client is html files served by web server such as nginx.
Second and last,
If we store accessToken in http cookie, is there any reason we use refreshToken?
Thanks! Great questions — super common in real apps.
Different domains (A.com app, B.com IdP/API):
A server on B.com can’t set cookies for A.com.
Use one of these:
Same-site setup: serve IdP on a subdomain (e.g. auth.a.com) so it can set a first-party HttpOnly cookie (SameSite=Lax/Strict).
Top-level redirect: briefly navigate the browser to b.com so it’s first-party there; B.com sets the cookie, then redirects back.
BFF pattern: tiny backend under a.com holds tokens; browser only has a session cookie.
Access token in an HttpOnly cookie — do we still need a refresh token?
For SPAs, don’t put the access token in a cookie (CSRF + it’s sent automatically everywhere). Keep access in memory and use Authorization: Bearer.
You still want a refresh token (in HttpOnly cookie) to renew short-lived access tokens without re-login (and to enable rotation/reuse-detection).
If you move to BFF + server session, then you typically don’t use access tokens in the browser at all (so no refresh token in the browser either).
I’ll cover these options (same-site vs redirect, PKCE, BFF, CSRF gotchas) in Part 2. 🚀
This was a nice article. I think I understand the concepts better now.
Thanks a lot 🙏
I am definitely going to share this with our team @jediswebdev_07a684996b15e
Thanks a lot 🙌
Really happy it helped make the concepts click — that’s exactly why I’m writing the series 🙂
Part 2 coming soon 🚀
The explanation was crisp and clear!!
Thanks for sharing this blog @sylwia-lask
Thank you so much! 🙌
Really happy to hear it was clear — that’s exactly what I was aiming for 🙂
Part 2 coming very soon! 🚀
I completely agree with you @priteshkiri
Great breakdown! To put it simply: authentication is about verifying who you are like showing your ID at the border. Once verified, authorization is about what you’re allowed to do like having the right visa or permissions to enter certain areas. In the tech world, the ID token confirms your identity, while the access token determines what actions or resources you can access. Understanding this helps clarify how secure systems manage user access efficiently!
We can never have too many mental models for auth. Each one offers its own unique perspective and gives us a chance to learn something new.
Thanks for your effort on this one!
Thanks so much 🙌
Totally agree — auth really clicks only once you’ve seen it from a few angles.
Glad this model added another lens to the toolkit 🙂
Cuan banget main di Jo777.