Carlos Cifuentes
Micro-frontends · Authentication

Sharing login and session across micro-frontends

Users log in once and expect every part of the product to know who they are. That only works reliably when exactly one piece of the platform owns authentication.

By Carlos Cifuentes · Frontend architect · Updated 2026-10-02

One owner

Exactly one part of the system owns login. In most platforms that is the host, through an auth library it initializes once.

Remotes never show a login form, never run their own OAuth flow and never store tokens of their own.

The usual flow

A common setup in enterprise applications is OpenID Connect with the authorization code flow and PKCE.

  1. The user opens any URL. The host starts.
  2. The host checks for a session. If there is none, it remembers the requested URL and redirects to the identity provider.
  3. After login, the identity provider redirects back. The host completes the code exchange and returns to the original URL.
  4. The host exposes the current user to the remotes, which load and call their APIs.

Step 2 is what lets a deep link survive the login. See Routing across micro-frontends.

Where the tokens live

ApproachHow it worksTrade-off
In memory, managed by the hostThe host keeps the access token in a variable and attaches it to requestsSimple. Scripts on the page can reach the token
Backend-for-frontend (BFF)A server component holds the tokens. The browser only has a session cookie marked HttpOnly, Secure and SameSiteTokens never reach JavaScript. Needs a server component and CSRF protection
localStorage or sessionStorageTokens persisted in browser storageReadable by any script, including one injected through XSS. Avoid

One fact is specific to micro-frontends. With runtime federation, every remote runs in the same JavaScript context as the host. Anything the host can read, a remote and its third-party scripts can read as well. That strengthens the case for the BFF pattern, which current OAuth guidance for browser-based applications recommends. The wider threat model is in Micro-frontend security.

How remotes get authenticated requests

  • A shared HTTP layer. In Angular, the host registers one HTTP interceptor that attaches the token to requests for known API origins. Remotes that use the shared HttpClient get this for free.
  • A small function. For remotes in another framework or wrapped as web components, a platform package exposes something like getAccessToken() that returns a promise.
  • With a BFF, nothing. The cookie travels with each request to the same site. Remotes make plain requests.

Never pass tokens in URLs, custom events or postMessage broadcasts.

Silent refresh

Access tokens are short-lived, so something has to renew them. Renewal belongs in one place: the auth owner, or the BFF on the server.

The classic problem is concurrency. Several requests fail with 401 at the same moment and each one tries to refresh. With rotating refresh tokens, the second attempt presents a token that was already used, and the identity provider may revoke the whole session. The fix is a single refresh in flight, with all other requests waiting for its result.

Renewal through a hidden iframe depends on third-party cookies, which browsers increasingly block. Do not design around it.

Logout

  • The host clears the session and calls the identity provider's end-session endpoint.
  • Remotes must drop cached user data. The most reliable way is a full page navigation to the login screen, which wipes all in-memory state at once.
  • Other tabs need to know. A BroadcastChannel message or a storage event lets each tab react.
  • Session expiry is handled in one place: the auth owner redirects to login and keeps the return URL.

Authorization

Login answers who the user is. What the user may do is checked in three places: the host for access to whole areas, each remote for its own screens, and the API for everything. Only the API check protects data.

Common mistakes

  • Each remote initializes its own auth library. The result is several redirects, competing refreshes and inconsistent user state.
  • The auth library is not a shared singleton. Two copies load, each with its own state. One knows the user and the other does not. See Shared dependencies and versions.
  • A remote registers its own HTTP client providers. Its requests bypass the host's interceptor and go out without a token.
  • Logout leaves cached data in remotes. The next user on a shared computer sees it.

Checklist

  1. Is there exactly one place in the code that starts a login?
  2. Is there a single refresh in flight under concurrent 401 responses?
  3. Does a deep link survive the login redirect?
  4. Does logout clear every remote's state and every open tab?

More in this section

Planning a migration or a micro-frontend platform?

In a 20-minute call you describe your situation and I tell you how I'd approach it. If it isn't worth doing yet, I'll say so.

Message me on LinkedIn