October DealsAmazon USOctober deal check: compare before you payAmazon US: current deals, useful picks and tech finds.Check DealsClean PCRecommendedOne scan can reveal what keeps slowing WindowsLook for cleanup and repair opportunities.Run ScanOctober DealsAmazon USDeal season is back - check today's better picksAmazon US: current deals, useful picks and tech finds.See Picks×
Skip to content
World desk7 min

How to Implement SPA Authorization Without Node.js or a JavaScript Framework

A single-page app does not need Node.js or a JavaScript framework for OAuth. This guide explains browser-only and BFF architectures, PKCE, redirect protection, token storage, refresh rules, and API authorization.
Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Yes. A single-page application can use OAuth 2.0 with ordinary browser JavaScript and a static web host. Use Authorization Code with PKCE, treat the browser as a public client with no secret, register an exact redirect URI, and choose deliberately between browser-only token handling and a backend-for-frontend (BFF). OAuth obtains tokens; your API must still decide what each user is allowed to do.

First separate OAuth from application authorization

OAuth gives a browser application an access token that it can present to a resource server. It does not automatically grant permission for every operation. Your API must validate the token and apply its own policy for the user, tenant, resource, action, and any relevant scopes or claims. This distinction is consistent with the OWASP Authorization Cheat Sheet and with the IETF draft OAuth 2.0 for Browser-Based Applications.

The IETF document used here is draft 27, dated July 2026, and expires on 7 January 2027. It is current draft guidance rather than a final RFC, so check the latest version when you implement or review the design.

Choose where OAuth responsibilities live

The absence of Node.js or a JavaScript framework does not determine the architecture. A BFF is a server role, not a Node.js product; it can be implemented with any suitable server technology. Conversely, a static site can perform OAuth entirely in the browser.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
Architecture Where tokens are handled How API calls travel Main advantage Main cost or exposure
Browser-only public client The browser exchanges the authorization code and handles access tokens; refresh tokens, if issued, are also exposed to browser-side handling. The browser calls the resource server directly with an access token. No application backend is required; a static host is sufficient. Token handling occurs in the browser, where malicious JavaScript can attack the application context.
Token-mediating backend An intermediate backend participates in token handling between the browser and authorization server. Some requests pass through the backend; exact routing and storage depend on the design. Provides an intermediate compromise between direct browser handling and a full BFF. It has different request-routing and token-exposure trade-offs and must not be treated as identical to a BFF.
Backend for Frontend (BFF) The BFF exchanges the code, associates tokens with a server-side session, and keeps OAuth tokens out of browser code. The browser calls the BFF; the BFF adds the access token when forwarding to the resource server. Browser JavaScript cannot directly read the BFF-managed OAuth tokens. Extra deployment, scaling, maintenance, and security responsibility; resource requests are routed through the BFF.

A BFF reduces direct token extraction from browser code, but it does not make a compromised browser harmless. Malicious code can still use the user’s live BFF session to send authenticated requests. The draft also warns that a BFF vulnerability can have significant impact because it concentrates security responsibility.

Implement a browser-only SPA on a static host

1. Register a public client

Register the application as a public browser client. Do not put a client secret in HTML, JavaScript, a source map, or any value delivered to users; everyone who receives the application can inspect it. Register the exact callback URI you will use, including scheme, host, path, and any required port. Do not rely on wildcard or loosely matched redirect registrations.

2. Generate a PKCE verifier and challenge

For every authorization attempt, create a high-entropy code_verifier and derive an S256 code_challenge. Authorization Code with PKCE is the recommended flow for browser applications. The draft says public browser clients using this flow must implement PKCE and authorization servers must support and enforce it.

const randomBytes = (length) => crypto.getRandomValues(new Uint8Array(length));
const base64url = (bytes) => btoa(String.fromCharCode(...bytes))
  .replace(/+/g, '-').replace(///g, '_').replace(/=+$/, '');

const verifier = base64url(randomBytes(32));
const digest = await crypto.subtle.digest(
  'SHA-256',
  new TextEncoder().encode(verifier)
);
const challenge = base64url(new Uint8Array(digest));

Keep the verifier associated with this browser tab until the callback arrives. Use an appropriate browser mechanism for that short-lived state and remove it after the exchange; do not treat any storage mechanism as immune to malicious code running in the application context.

Free tools Windows power users keep installed

One-click scans. No signup required.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
Rank #2
Sale
HTML and CSS: Design and Build Websites
  • HTML CSS Design and Build Web Sites
  • Comes with secure packaging
  • It can be a gift option

3. Bind and protect the redirect request

Create a unique, unguessable state value, retain it for the callback, and reject a response whose state does not match. The draft identifies enforced PKCE, a unique verified OAuth state, or, for OpenID Connect, a verified nonce as protections against redirect-flow CSRF. Use the mechanisms required by your protocol and verify them before processing the authorization code.

4. Redirect to the authorization endpoint

Send the user to the authorization server with parameters equivalent to:

  • response_type=code
  • the registered client_id
  • the exact redirect_uri
  • the requested scope
  • the generated state
  • code_challenge and code_challenge_method=S256

The authorization server authenticates and obtains the user’s consent according to its policy, then redirects back with a short-lived authorization code.

5. Verify the callback and exchange the code

On the callback route, first verify the returned state (and nonce when using OpenID Connect). Reject errors, unexpected issuers, and an unrecognized redirect context. Exchange the one-time code at the token endpoint, sending the original code_verifier, client ID, and exactly the same redirect URI. Never send a client secret because this is a public client.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

6. Call the resource server

Keep the access token only as long as your threat model permits and send it over HTTPS in the resource server’s expected authorization header:

const response = await fetch('https://api.example.test/profile', {
  headers: { Authorization: `Bearer ${accessToken}` }
});

The resource server must validate the token and then enforce whether this user may perform the requested operation. A successful token exchange or login is not an authorization decision for every endpoint.

Make browser token storage a threat-model decision

Storage choices change exposure; none makes malicious code in the application context safe. Widely accessible storage such as Local Storage is easier for malicious JavaScript to reach than more isolated arrangements such as a Web Worker. That is a relative isolation difference, not a guarantee that a Web Worker defeats an attacker who can execute code in the application context.

  • Short-lived in-memory handling: limits persistence but requires a new flow after a reload or tab loss.
  • More isolated browser arrangements: can reduce direct access from ordinary page scripts, but still require careful message handling and do not neutralize XSS or compromised remote code.
  • Local Storage: convenient and persistent, but readily accessible to JavaScript running in the page.

Choose based on the damage an attacker could cause, how often users must reauthenticate, and whether your application can tolerate losing tokens on reload. Do not claim that any browser storage option eliminates token theft.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
Rank #4
Sale
Web Design with HTML, CSS, JavaScript and jQuery Set
  • Brand: Wiley
  • Set of 2 Volumes
  • A handy two-book set that uniquely combines related technologies Highly visual format and accessible language makes these books highly effective learning tools Perfect for beginning web designers and front-end developers

Use a BFF when you want server-managed tokens

With a BFF, the browser begins authorization through the BFF rather than exchanging the code itself. The BFF performs the code exchange, associates the resulting tokens with the user’s server-side session, and sets a session cookie. Later browser requests go to the BFF; it adds the access token when forwarding to the resource server. The browser never receives the OAuth access or refresh token directly.

  1. The browser navigates to a BFF authorization route.
  2. The BFF creates and records the authorization transaction, then redirects to the authorization server with PKCE and the redirect URI.
  3. The authorization server returns the code to the BFF callback.
  4. The BFF verifies the transaction and exchanges the code.
  5. The BFF stores or otherwise protects the token association on the server and sets a cookie with both Secure and HttpOnly.
  6. The browser calls BFF endpoints; the BFF forwards permitted requests with the access token and returns the resource response.

This design adds a backend that must be deployed, scaled, monitored, patched, and protected. It also means resource requests pass through that backend. A BFF limits direct token reading by browser code, but XSS can still issue requests through the authenticated session, so API authorization and session controls remain essential.

Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Handle refresh, logout, and expiry explicitly

Refresh tokens

If a browser client receives refresh tokens, treat them as more persistent credentials than access tokens. The IETF draft calls for rotation on every use or sender-constrained refresh tokens, plus a maximum lifetime or expiration after inactivity. A rotated refresh token must not extend beyond the established initial lifetime. Enforce the authorization server’s reuse and revocation behavior, and discard client-side copies when the session ends.

Logout and session expiry

Logout should clear the application’s local session state. In a BFF, invalidate the server-side session and its token association, then expire the cookie. Access-token expiry and refresh failure must return the application to a signed-out state rather than leaving a loop of failed API calls. Provider-side logout behavior is deployment-specific; do not assume that clearing a browser variable revokes a token at the authorization server.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Security checklist for a framework-free implementation

  • Use Authorization Code with PKCE and S256 for the public browser client.
  • Never ship a client secret in browser-delivered code.
  • Register and use an exact redirect URI; reject unexpected callback destinations.
  • Generate and verify a unique state value for each flow, or verify an OpenID Connect nonce where applicable.
  • Use HTTPS for the application, callback, token exchange, and API requests.
  • Document where access and refresh tokens live and which scripts can reach them.
  • If refresh tokens reach the browser, require rotation or sender constraint and a bounded lifetime or inactivity expiry.
  • Assume XSS or compromised remote JavaScript can act as the user, even when a BFF hides token values.
  • Make the resource server enforce user- and resource-level permissions instead of trusting login success.
  • Review the latest IETF draft before release because draft requirements can change.

Which design should you choose?

Choose browser-only when

A static deployment is important, your team accepts browser token exposure, and the resource server can safely accept calls from the browser. Keep access tokens short-lived where practical and make the storage and refresh trade-off explicit.

Choose a BFF when

You want OAuth tokens kept out of browser-readable state, can operate a backend, and accept routing API traffic through it. Treat the BFF as a high-value security boundary rather than as a token-hiding shortcut.

Evaluate token mediation separately

A token-mediating backend can fit systems that need an intermediate arrangement, but its exact security properties depend on which requests it handles and where tokens reside. Document those details instead of labeling it a full BFF.

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Leave a Reply

Your email address will not be published. Required fields are marked *

What’s actually slowing this PC down?

Pick the symptom - the matching free tool is one click away.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

More from the Wire

  1. Shenzhen desk3 min
    HONOR Expands Beyond Smartphones With Humanoid Robot RevealHONOR said it unveiled its first humanoid robot at MWC 2026 and named shopping assistance, workplace inspections, and supportive companionship as intended uses. Later Robotics D1 claims and a reported…
  2. Cupertino desk5 min
    Apple Unveils AirPods Max 2: The Upgrade That Should Have Happened Years AgoAirPods Max 2 adds H2-powered audio features and Apple claims up to 1.5× more effective ANC, but its design, Smart Case, and 20-hour battery rating are unchanged. Wired lossless audio…
  3. Cupertino desk4 min
    Apple’s OLED Touch MacBooks Are Coming—but the Dynamic Island Is the Real GambleApple has not announced an OLED touchscreen MacBook, but reports point to high-end models arriving in late 2026 or early 2027. The reported Mac Dynamic Island could be useful, but…
Recommended PC Tool
Recommended PC Tool
PC Slower Than It Used to Be?Free scan - under a minute
Crashes, No Sound, or Screen Glitches?Free driver scan

Two free Windows tools

One Free Minute Could Fix That PC

Before you go - each of these free tools takes about a minute and tackles what quietly slows a Windows PC down.

Special offer. View Outbyte info, uninstall instructions, EULA, and Privacy Policy.