OAuth 2.1: What’s new, what’s gone, and how to migrate securely
Learn what’s changed in OAuth 2.1, including the removal of implicit flow, mandatory PKCE, and modern refresh token strategies. This guide walks you through the security upgrades and offers a clear migration checklist to help you stay compliant and secure.
OAuth 2.0 has become the de facto standard for delegated authorization on the web. It underpins login and API access flows across countless applications, services, and identity providers. But as widespread adoption brought more implementation patterns—and misuses—it also became clear that a refined, clearer specification was needed. Enter OAuth 2.1.
In this article, we’ll walk through what’s new, what’s deprecated, and what you need to know about the evolution of OAuth.
!!TL;DR: OAuth 2.1 is a cleanup and consolidation—not a revolution. But it officially drops risky flows like implicit grants, mandates PKCE everywhere, and lays down a clearer, more secure path for building modern apps.!!
Why OAuth 2.1?
OAuth 2.0 has been around since 2012 and has seen widespread use—and misuse. Over time, the spec has splintered across dozens of extensions, security best practices, and ambiguous edge cases. OAuth 2.1 isn’t a ground-up rewrite. Instead, it’s a curated update that:
- Consolidates key security improvements from multiple RFCs
- Deprecates legacy or unsafe flows
- Provides clearer guidance to developers and implementers
Rather than re-invent the wheel, OAuth 2.1 builds directly on OAuth 2.0 and includes guidance from related specifications like:
- OAuth 2.0 Security Best Current Practice (BCP)
- OAuth 2.0 for Browser-Based Apps
- Proof Key for Code Exchange (PKCE)
- OAuth 2.0 for Native Apps
What’s new (and what’s gone)
1. PKCE is now mandatory
Originally introduced for mobile and native apps, Proof Key for Code Exchange (PKCE) is now required for all authorization code flows—including server-side clients. PKCE helps prevent authorization code interception attacks by adding a layer of client-specific verification.
How it works:
- Client generates a
code_verifier
(random string) and transforms it into acode_challenge
- The
code_challenge
is sent with the initial auth request - Later, the
code_verifier
is sent with the token request, and must match the original challenge

PKCE neutralizes authorization code interception attacks by tying the token exchange to the originating client instance.
2. Implicit flow is removed
The implicit flow (where tokens are returned directly via the URL fragment) is no longer part of the spec. This change is due to its known security risks—most notably token leakage in browser history or logs.
If you're using SPAs, switch to authorization code + PKCE—modern browsers now support CORS, same-origin policies, and fetch()
securely enough to handle this.
3. Refresh tokens for SPAs (securely)
OAuth 2.1 formalizes how single-page apps (SPAs) can securely use refresh tokens, leveraging secure HTTP-only cookies or trusted storage mechanisms with modern browser APIs. This is a shift from the earlier pattern of forcing users to reauthenticate frequently.
OAuth 2.1 allows public clients like SPAs to use refresh tokens, provided they:
- Use secure HTTPS-only cookies for token storage, or
- Use IndexedDB or Web Storage with strict controls
- Implement Refresh Token Rotation (RTR). Each time a refresh token is used to acquire a new access token, a brand new refresh token is also generated and the previous one is invalidated.
4. Bearer tokens remain—but use them carefully
In OAuth, a bearer token is an access token that grants access to a resource without any additional proof of possession. Whoever holds the token — in memory, in a browser, in transit — can use it. That’s why it’s called a "bearer" token: possession equals permission.
The problem? If someone steals that token, they can impersonate the client or user — whether they're the legitimate party or not. Common attack vectors include:
- Man-in-the-middle attacks on insecure connections
- JavaScript access via XSS
- Logging tokens in browser history or server logs
- Token replay from intercepted network traffic
OAuth 2.1 does not deprecate bearer tokens, but it heavily emphasizes secure transport and scope minimization to mitigate these risks:
- Always use HTTPS: This is non-negotiable. The transport layer (TLS) must be trusted and validated to protect token confidentiality during transit.
- Minimize token scope and lifetime: Use narrowly scoped tokens that limit:
- What they can access (e.g.,
read:user
instead of full access) - How long they are valid (short-lived tokens reduce replay risk)
- What they can access (e.g.,
- Secure storage on the client: Tokens should never be stored in LocalStorage (vulnerable to XSS) or URL fragments (visible in browser history or logs). Instead:
- Use secure, HTTP-only cookies
- Or use memory-only storage with refresh token rotation
OAuth 2.1 does not mandate sender-constrained tokens, but it acknowledges them as stronger alternatives. These bind the access token to a specific client or device. Examples:
- Mutual TLS (mTLS)
- The client must present a TLS certificate when using the token
- Resource server verifies the client matches the certificate originally used
- DPoP (Demonstration of Proof-of-Possession)
- A lightweight alternative to mTLS
- The client signs each request with a key pair and includes a DPoP proof header
DPoP ensures:
- The token can only be used by the holder of the private key
- Prevents token replay from a different client
These are not required in OAuth 2.1, but you should keep them in mind for high-risk scenarios, like financial services, healthcare, or regulated industries.
5. Redirect URIs: No more wildcards
OAuth 2.1 simplifies validation by requiring exact match of redirect URIs for all clients. Wildcard or partial matches are discouraged to prevent open redirect vulnerabilities.
Bad:
Good:
This prevents open redirect vulnerabilities and misrouted token deliveries.
6. Password grant is deprecated
The Resource Owner Password Credentials (ROPC) grant—where apps collect a user’s username and password directly—is officially deprecated. This insecure pattern had long been discouraged and is now formally excluded.
Instead you should use:
- The Device Authorization Flow for non-browser interfaces.
- The Authorization Code + PKCE for user-facing apps.
OAuth 2.0 vs OAuth 2.1
Implementation guidance
OAuth 2.1 provides clear recommendations for modern app types:
- Browser-based apps: Use authorization code flow + PKCE + secure refresh handling.
- Mobile/native apps: Use authorization code flow + PKCE, with app-specific redirect URIs.
- Server-side apps: Continue using client secrets but now add PKCE support.
- Public clients: Be extra cautious with token storage; avoid implicit flows.
For authorization servers and libraries, OAuth 2.1 provides a more prescriptive roadmap to secure defaults.
Migration checklist
- Implement PKCE for all clients (public and confidential)
- Generate and send
code_challenge
- Require and validate
code_verifier
on token request
- Generate and send
- Remove usage of
code_challenge_method=plain
, unless truly unavoidable (e.g. legacy) - Use short-lived authorization codes and tokens
- Validate exact
redirect_uri
match on every authorization request - Eliminate use of the Implicit Flow (
response_type=token
) - Deprecate Resource Owner Password Credentials (ROPC) grant
- Securely store access/refresh tokens
- Use memory only, secure cookies, or IndexedDB—not LocalStorage
- Implement Refresh Token Rotation (RTR) for SPAs
- Detect reuse of old refresh tokens
- Invalidate tokens on replay
- Narrow token scopes to least privilege needed
- Optionally explore sender-constrained tokens (DPoP, mTLS) for highly sensitive apps
What's not changing?
- The core protocol mechanics—authorization requests, token issuance, and scopes—remain familiar.
- Existing OAuth 2.0 implementations remain valid. OAuth 2.1 is backward-compatible where possible but nudges implementers toward safer defaults.
When will OAuth 2.1 be final?
OAuth 2.1 is still in draft status as of this writing, but it's being actively iterated and widely adopted in practice. Major libraries and identity providers are aligning with its principles even before final publication.
How WorkOS can help
Navigating the transition to OAuth 2.1 can be complex — from implementing PKCE correctly to securely handling refresh tokens and deprecating legacy flows.
WorkOS simplifies OAuth 2.1 adoption by providing a turnkey, enterprise-ready OAuth 2.0 platform that already aligns with modern security best practices. With built-in support for Authorization Code + PKCE, exact redirect URI enforcement (we only allow wildcards in staging envs), refresh token rotation, and secure token storage patterns, WorkOS helps you accelerate compliance while eliminating boilerplate.
Whether you're upgrading an existing app or building new integrations, WorkOS makes implementing secure, standards-compliant auth flows effortless — so you can focus on building great user experiences, not protocol minutiae.