Skip to main content
N'doua Adé Kouadio MOLOU
All writing
Note2 min read

Where the access token lives

The browser should hold nothing, says the best practice. It is right. What remains is what it costs on an internal tool with thirty users — and what an httpOnly cookie does not prevent.

An Angular application, a Spring Boot API, an identity server. What is left is a question that looks like an implementation detail, and decides everything that follows: does the browser receive the access token, or only a session cookie?

Two answers, both defensible

The BFF. An intermediate service holds the token. The browser receives only an httpOnly session cookie, which the page's JavaScript cannot read. This is the direction current best practice recommends for browser applications.

The public client SPA. The application obtains its own token through the authorization flow with PKCE, keeps it in memory, and sends it to the API. One less service to write, deploy and watch. No session to hold. The token disappears when the tab closes.

What the BFF actually buys

An XSS flaw steals nothing, because there is nothing to steal. The token, its lifetime, its scopes and its renewal stay out of the browser's reach — and therefore out of reach of an injected script, a compromised dependency, or an analytics tag placed by someone other than you.

What it costs, and what is rarely announced

  • One more service. To write, to deploy, to watch, to keep updated.
  • State. A session to hold somewhere — memory, cache, database — where the SPA had nothing to hold.
  • CSRF comes back. It had gone away with the cookie; it returns with it.
  • One more hop on every call, and one more point of failure on the path.

What both camps forget

This is the point most often missing from the debate, and it is the most important one. The httpOnly cookie prevents exfiltration, not abuse.

A script injected into the page does not read the cookie — but it does not need to. It sends its requests from the page, and the browser attaches the cookie by itself.

So the BFF narrows the window rather than closing the door: a stolen token works elsewhere and for a long time, a hijacked session works only there, and only as long as the tab lives. That is a real gain, and it does not remove the step that matters — not having XSS.

The criterion

"Recommended" is not "always justified". The question to ask is not which pattern is best regarded this year, but: what is worth what the token opens?

An internal tool with thirty users, whose worst case is an employee seeing a dashboard that does not concern them: the running cost of a BFF probably exceeds the gain.

An application that triggers payments, corrects prices or opens tills: the calculation flips, and it flips all at once.

A second question, asked less often: who will run that service in two years? A BFF nobody updates any more is not a protection — it is one more exposed server.

What I take from it

There is no answer independent of what is being protected. There is a best practice, a running cost, and a value on the other side. The only bad choice is the one made without having weighed all three.

Topics

  • OAuth 2.0
  • BFF
  • Angular
  • Sécurité
  • Architecture

Did this help?

Share

Let us talk about what you want to build

A question, a project, or simply a conversation: write to me.