A practical pattern is to separate login from backend access. Use an authentication service to issue a session after the user proves control of an email address, then validate that session on every protected API call before touching data. That keeps the user experience lightweight while preserving a clear server-side trust boundary and preventing direct unauthenticated access to sensitive endpoints.
Design the login flow so authentication and API access stay separate
Keep the first exchange lightweight and purpose-built: the user proves control of an email address or other login factor, the authentication service issues a session, and only then does the application call protected backend APIs. That separation lets you preserve a normal user experience without making the backend trust every browser request as if it were already authenticated.
For teams, the key design choice is not whether to have an API, but where trust starts. The browser-facing layer can handle sign-in, redirects, and session state, while the backend should only accept requests that present a valid session or token established by that front-door flow.
Validate the session before any sensitive data or action is touched
Every protected request should be checked on the server side before it reaches business logic, database queries, or privileged operations. That validation can be a cookie-backed session, a signed token, or another authenticated context, but it must be enforced at the API boundary rather than only in the user interface.
This pattern prevents a common failure mode where the frontend looks secure but the backend still responds to direct calls. If the API can be reached without a trusted session check, an attacker can skip the user interface entirely and probe the backend for data, actions, or object identifiers.
Keep the user experience simple without weakening the trust boundary
A usable design does not require exposing backend APIs to unauthenticated requests. Instead, keep the authentication step short, avoid unnecessary friction, and let the application reuse the resulting authenticated context for the rest of the session. Good session design reduces repeated logins while still keeping the backend behind a clear trust boundary.
That usually means limiting the surface area of public endpoints to only what is needed for sign-in, account recovery, and other pre-authentication tasks. Everything else should remain behind authenticated access so the system can scale usability and security together rather than trading one away for the other.
Risk and Threat Considerations
The main risk is not just unauthorized data exposure, but also backend abuse through direct request forging. If unauthenticated traffic can reach protected APIs, attackers can enumerate endpoints, test object references, and automate requests without ever passing through the user-facing login flow.
Failure mechanism: The application treats frontend state as proof of identity, or the backend trusts requests that were never bound to a valid session or authenticated principal.
Impact: Sensitive data can be disclosed, unauthorized actions can be executed, and the attack surface becomes much easier to probe and automate at scale.
Standards & Framework Alignment
This section maps relevant standards and security frameworks to the operational risks and controls described in this guidance.
OWASP ASVS and NIST SP 800-53 Rev 5 set the governance and control requirements practitioners need to meet.
| Framework | Control / Reference | Relevance |
|---|---|---|
| OWASP ASVS | V6 — Authentication | Covers user sign-in and proof of identity before access is granted. |
| V7 — Session Management | Applies because the design depends on a valid session after login. | |
| V8 — Authorization | Relevant because backend endpoints must not accept actions without access checks. | |
| Recommendation — Require authenticated sessions before protected requests reach application logic. Validate session state on every protected API call and reject unauthenticated traffic. Enforce authorization at the API boundary before any sensitive action or data access. | ||
| NIST SP 800-53 Rev 5 | IA-2 — Identification and Authentication (Organizational Users) | Supports server-side authentication of users before access to protected functions. |
| AC-3 — Access Enforcement | Applies because the backend must enforce access rules, not the client UI. | |
| IA-5 — Authenticator Management | Relevant to issuing, validating, and protecting sessions or tokens used after login. | |
| Recommendation — Authenticate users before allowing access to protected backend endpoints. Enforce access decisions on the server for every protected request. Manage session or token lifecycles so authenticated state remains trustworthy. | ||
Practitioner Guidance
What to verify: Confirm that every protected API route enforces authentication on the server side, not just through hidden UI elements or client-side checks. Review the unauthenticated route list and keep it as small as possible, with explicit justification for each public endpoint.
Decision rule: If a request can affect account state, customer data, or internal business logic, require a validated session before the handler runs. If the request is only part of sign-in or recovery, isolate it from the rest of the API surface and treat it as a special-case entry point.
Practitioner takeaway: Usability and backend protection are compatible when the app authenticates once at the edge, then enforces trust consistently on every protected call.
Related resources from NHI Mgmt Group
- How should security teams orchestrate customer identity journeys without exposing backend APIs?
- How should teams implement authentication for protected pages in a Next.js application without exposing unauthorized content?
- How should organisations design multi-factor authentication so it stays usable without weakening security?
- How should security teams design authentication analytics to improve user support and compliance without adding friction?