Passwordless sign-in can be both low-friction and robust when the browser never handles the session directly. Here is a practical BFF pattern, its limits and the decisions that matter.

Passwordless authentication is not automatically safer than passwords. The useful security boundary is where the session lives. A backend-for-frontend (BFF) keeps the browser focused on the interface while the server exchanges, refreshes and protects the session.
This pattern suits products with sensitive data, several user roles or more than one web application. It draws on lessons from building a real-world platform, including Drivio, but the implementation below is deliberately generic. No product-specific routes, identifiers or security controls are disclosed.
A one-time code or magic link means the product does not have to store, reset or defend a reusable password. It does not eliminate phishing, inbox compromise or automated guessing. Rate limits, short expiry, attempt limits and a clear recovery route remain part of the design.
For browser-based OAuth clients, the IETF describes a BFF as one of the recommended architectures because it can keep tokens away from the browser and use a secure, HttpOnly cookie between browser and backend. Read the OAuth guidance for browser-based applications before choosing an architecture, especially where the product uses third-party identity providers.
The result is a useful division of labour. The browser sends a request to its own backend. The backend deals with the identity provider and returns only the rendered page or API response. This is not security by obscurity. It is reducing how many places can accidentally expose a session.
An HttpOnly cookie prevents page JavaScript from reading it. A Secure cookie is sent only over HTTPS. SameSite changes when it accompanies cross-site requests. These are distinct controls, and the OWASP session-management guidance explains their role and limits.
Use the smallest practical cookie scope. A host-only cookie is usually simpler and safer than a parent-domain cookie. If single sign-on genuinely needs a shared domain, ensure every receiving host is trusted, use different secrets per environment, and include enough environment context to reject a cookie issued elsewhere.
Every state-changing endpoint should follow one well-tested route shape: accept only the content types it expects, verify the request origin or CSRF token, read the session server-side, enforce authorisation, return non-cacheable private data and log the event without secrets.
SameSite is helpful but should not be the whole CSRF strategy. Sibling subdomains are considered same-site, which is why OWASP recommends treating same-site requests cautiously when not every sibling host is fully trusted. See its CSRF prevention guidance on same-site subdomains and Origin checks.
A BFF can make session handling safer and easier to reason about. It should not become a second, drifting permission system. The API and database still need to check who may read or change each resource. Next.js makes the same distinction: authentication establishes identity, session management tracks state and authorisation decides access.
That distinction also makes code review sharper. A reviewer can ask whether a route correctly establishes identity, then separately ask whether the underlying operation is allowed. One successful email-code check should never become an implied permission to view a different customer, tenant or role.
The value of a BFF is not a clever login screen. It is making the safe route the easy route for every feature that follows. Passwordless sign-in then becomes a calm entry point to a product whose real permissions are still enforced exactly where they belong.
No. It proves control of a sign-in factor but still needs rate limiting, session protection, safe recovery and server-side authorisation.
No. HttpOnly prevents JavaScript from reading the cookie. Browsers can still attach cookies to requests, so state-changing endpoints need CSRF defences.
It is especially useful when a browser app handles sensitive data, needs multiple frontends to share an auth pattern or wants to keep identity-provider credentials out of browser JavaScript.
Ready when you are