Implement OAuth correctly to protect your users. Common mistakes and how to avoid them.
Proof Key for Code Exchange prevents authorization code interception attacks. Required for public clients, recommended for all.
Prevent CSRF attacks by including a random state parameter and validating it on callback.
Only allow exact match redirect URIs. No wildcards, no open redirects.
Never store tokens in localStorage or expose to JavaScript. Use httpOnly cookies or secure server-side storage.
Limit damage from token theft with short expiration. Use refresh tokens for longer sessions.
Only request permissions your app actually needs. Reduces blast radius if compromised.
Risk: XSS attacks can steal tokens
Fix: Use httpOnly cookies or server-side session storage
Risk: CSRF attacks can link attacker's account
Fix: Always generate, store, and validate state
Risk: Code reuse attacks
Fix: Invalidate codes after first use
Risk: Open redirect attacks can steal codes
Fix: Only allow exact match redirect URIs
Risk: Authorization code interception
Fix: Always use PKCE for public clients
Risk: Extended window for token abuse
Fix: Use short-lived access tokens with refresh tokens
Use for: SPAs, mobile apps, server-side apps
Most secure flow for most use cases
Use for: Traditional server-rendered apps
Secure when client secret stays server-side
Use for: Legacy only—avoid for new apps
Deprecated. Token exposed in URL fragment.
Use for: Server-to-server authentication
No user involved. Secure for machine-to-machine.
VAS scans your application for common OAuth security issues including token exposure, missing PKCE, and insecure storage patterns.
Free Security ScanTechnically not required for confidential clients with a client secret, but it adds defense in depth and is recommended. PKCE protects against authorization code interception even if the secret is compromised. Many OAuth providers now recommend or require it for all clients.
For web apps: httpOnly, secure, sameSite cookies for access tokens—they can't be stolen via XSS. For refresh tokens: httpOnly cookies or encrypted server-side storage. Never use localStorage or sessionStorage for tokens.
Implement refresh token rotation—issue a new refresh token with each use and invalidate the old one. Store refresh tokens securely (httpOnly cookie or server-side). Set reasonable expiration and require re-authentication periodically.
State prevents CSRF on the authorization request—it links the request to the session. Nonce (in OpenID Connect) prevents replay attacks on ID tokens—it links the token to the authentication request. Use both when implementing OIDC.
Use a well-maintained library or OAuth provider SDK. OAuth has many subtle security requirements that are easy to get wrong. Libraries like NextAuth, Auth0 SDKs, or Passport.js handle the security details for you.
Last updated: January 16, 2026