As of October 1, 2026, OAuth 2.1 is not a final IETF standard. The current document is draft-ietf-oauth-v2-1-16, published on September 3, 2026. Comparing it with OAuth 2.0 is still useful because the draft consolidates years of security corrections around RFC 6749, including PKCE, the OAuth Security Best Current Practice, and guidance for native and browser-based applications.
For developers, the useful question is not whether a provider already displays a "2.1" label. It is which older OAuth 2.0 patterns should no longer be used in a new project and which protections are already best current practice today.
OAuth 2.0 and OAuth 2.1 at a glance
| Area | Original OAuth 2.0 | OAuth 2.1 draft |
|---|---|---|
| Authorization Code | defined without PKCE in the core | PKCE is part of the default flow |
PKCE plain |
defined by RFC 7636 | removed, use S256 |
| Implicit Grant | defined | omitted |
| Resource Owner Password Credentials | defined | omitted |
| Redirect URI | original matching rules | exact URI matching |
| Refresh tokens for public clients | limited core requirements | sender-constrained or one-time use |
| Bearer token in query string | allowed by RFC 6750 | omitted |
redirect_uri at token endpoint |
used in OAuth 2.0 code flow | removed from the OAuth 2.1 flow |
This does not mean a modern OAuth 2.0 deployment should behave like the left column. RFC 9700, published in January 2025 as an IETF Best Current Practice, already deprecated several historical patterns and introduced stricter requirements. OAuth 2.1 brings those changes into the framework itself.
OAuth 2.1 is a consolidation, not a clean-sheet protocol
OAuth 2.0 was standardized in RFC 6749 in 2012. Since then, important security properties have arrived through separate specifications: PKCE in RFC 7636, guidance for native apps in RFC 8252, the security BCP in RFC 9700, and browser application guidance in RFC 10017.
The OAuth 2.1 draft reduces that fragmentation. Its differences section explicitly says the framework consolidates OAuth 2.0, Bearer Token Usage, PKCE, OAuth for Native Apps, the OAuth Security BCP, and the work on browser-based applications.
The practical result is that behaviors which were technically available in OAuth 2.0 but later became discouraged are no longer part of the main framework.
PKCE becomes part of the Authorization Code flow
PKCE, Proof Key for Code Exchange, prevents an intercepted authorization code from being redeemed by a client that did not initiate the authorization request.
The client creates a random code_verifier, hashes it with SHA-256, and sends the resulting code_challenge to the authorization endpoint. When the authorization code is exchanged for a token, the original verifier is presented. The authorization server can then confirm that the party redeeming the code is the same client instance that started the flow.
In OAuth 2.1, PKCE parameters are part of the normal Authorization Code flow. The PKCE plain method is explicitly forbidden, leaving S256.
A browser-side JavaScript example:
function base64url(bytes) {
return btoa(String.fromCharCode(...bytes))
.replace(/\+/g, "-")
.replace(/\//g, "_")
.replace(/=+$/, "");
}
const random = new Uint8Array(32);
crypto.getRandomValues(random);
const codeVerifier = base64url(random);
const digest = await crypto.subtle.digest(
"SHA-256",
new TextEncoder().encode(codeVerifier)
);
const codeChallenge = base64url(new Uint8Array(digest));
The authorization request can then include:
GET /authorize?
response_type=code&
client_id=my-client&
redirect_uri=https%3A%2F%2Fapp.example.com%2Fcallback&
scope=openid%20profile&
state=RANDOM_STATE&
code_challenge=PKCE_CHALLENGE&
code_challenge_method=S256
At the token endpoint, the client sends the authorization code with the original verifier:
const response = await fetch("https://auth.example.com/token", {
method: "POST",
headers: {
"Content-Type": "application/x-www-form-urlencoded"
},
body: new URLSearchParams({
grant_type: "authorization_code",
client_id: "my-client",
code,
code_verifier: codeVerifier
})
});
Confidential clients still use the client authentication mechanism required by the authorization server. PKCE does not replace client authentication. It protects the authorization code against interception and injection.
The Implicit Grant is gone
RFC 6749 defined the Implicit Grant for clients that received an access token directly in the authorization endpoint response. It became common in older single-page applications at a time when browser capabilities and cross-origin patterns were more limited.
OAuth 2.1 omits response_type=token. RFC 9700 had already deprecated the Implicit Grant because an access token exposed through the front channel is harder to protect against leakage and injection, and cannot be sender-constrained in the same way.
For modern SPAs, the current reference is RFC 10017, published in August 2026. It uses Authorization Code with PKCE as the baseline for browser-based applications and also analyzes architectures with a server-side component, including the Backend for Frontend pattern, when the threat model calls for keeping tokens away from directly accessible JavaScript.
That does not mean every SPA needs a BFF. It means the architecture should be chosen with explicit answers about where access and refresh tokens live, what an XSS can reach, and which protections a backend can provide.
Resource Owner Password Credentials is removed
The Resource Owner Password Credentials grant, usually called ROPC or the password grant, allowed a client to collect a user's username and password and exchange them directly for an access token.
That conflicts with one of OAuth's useful security boundaries: the client should not need to know the resource owner's credentials. The model also interacts poorly with MFA, federated authentication, passkeys, and other authentication methods owned by the authorization server.
OAuth 2.1 omits this grant entirely, following RFC 9700.
If a new application is still designing a login form that captures the password and then calls a token endpoint with grant_type=password, the issue is not simply future OAuth 2.1 compatibility. The authentication architecture itself needs to change.
Redirect URI matching becomes exact
Redirect URIs are a security boundary in OAuth. If an authorization code can be redirected to attacker-controlled infrastructure because of permissive URI matching, a configuration shortcut becomes a credential theft path.
RFC 9700 requires exact string matching between the received redirect URI and a registered URI, with the defined exception for dynamic loopback ports in native applications. OAuth 2.1 incorporates this rule.
Loose configurations such as:
https://app.example.com/*
or validation that checks only the domain do not match the BCP model.
Register the actual redirect endpoint:
https://app.example.com/oauth/callback
Open redirectors deserve the same scrutiny. A client endpoint that accepts an arbitrary destination can become part of a chain that leaks an authorization code or token.
Refresh token handling changes too
For a public client, a refresh token is a high-value credential. If it is copied, possession alone may allow an attacker to obtain new access tokens for far longer than the lifetime of the original access token.
OAuth 2.1 adopts the RFC 9700 rule that refresh tokens for public clients must be sender-constrained or one-time use. With rotation, the authorization server can detect reuse of a refresh token that has already been consumed.
This matters directly to native applications and browser clients that cannot protect a static client secret like a backend can.
OAuth tokens are not an abstract risk. In our analysis of the 2026 Vercel breach, OAuth grants and tokens stored by a third-party service became high-value credentials after that service was compromised.
Bearer tokens in the query string are out
RFC 6750 included a method for sending a bearer token in a URI query string. OAuth 2.1 omits it, following RFC 9700.
A request such as:
GET /api/profile?access_token=eyJ...
puts the token in places that an Authorization header avoids: browser history, reverse proxy and web server logs, analytics systems, referrers, and other tooling that treats URLs as observable data.
The normal form remains:
Authorization: Bearer eyJ...
Again, this is not a reason to wait for OAuth 2.1. It is already the safer design for current OAuth deployments.
The token request no longer includes redirect_uri
One less visible difference matters when comparing implementations.
In the OAuth 2.0 authorization code flow, the token request can include redirect_uri, and RFC 6749 requires it in certain situations. The OAuth 2.1 draft removes the parameter from the token request because code_challenge and code_verifier now bind the authorization transaction.
The draft also defines backwards compatibility. An authorization server supporting both OAuth 2.0 and OAuth 2.1 clients must continue accepting the parameter from legacy OAuth 2.0 clients and enforce the RFC 6749 rules for them.
This is why copying one token request from a tutorial is a poor implementation strategy. The correct request depends on the profile and behavior supported by the authorization server.
OAuth 2.1 does not replace OpenID Connect
OAuth is an authorization framework for access to protected resources. It does not by itself define a login protocol that lets the client establish the user's identity.
Federated authentication commonly uses OpenID Connect on top of OAuth. An access_token says that a client can access certain resources. Applications should not interpret an arbitrary access token as proof of user identity.
That distinction remains intact with OAuth 2.1. The authorization framework changes, not the conceptual boundary between OAuth and OpenID Connect.
CSRF and redirect-flow protections also remain part of the application model. The f-hack guide to CSRF covers the web application attack class, while RFC 9700 explains how state, PKCE, and nonce fit into OAuth and OpenID Connect flows.
What to use in a new project in 2026
You do not need to wait for OAuth 2.1 to become an RFC before dropping patterns that are already deprecated.
For a new project, a sensible baseline is Authorization Code with PKCE S256, exact registered redirect URIs, no Implicit Grant, no password grant, and bearer tokens carried in the Authorization header.
Public clients need an explicit refresh-token strategy. Browser-based applications should be designed with RFC 10017 in hand before deciding whether tokens are managed entirely in the browser or mediated by a backend.
Modern authorization servers should also publish standardized metadata. In higher-security deployments, mechanisms such as DPoP or mutual TLS can be used to sender-constrain access tokens.
Not all of these features are unique to OAuth 2.1. That is the central migration point: moving toward OAuth 2.1 often means correctly adopting the specifications and BCPs that have hardened OAuth 2.0 over time.
Migrating an existing OAuth 2.0 implementation
The first useful check is not whether the provider has an "OAuth 2.1" toggle. Inventory the flows your application actually uses.
If you find response_type=token, an Implicit flow still exists. If you find grant_type=password, the client is handling user credentials directly. If Authorization Code is used without PKCE, confirm provider support and plan the migration.
Then review registered redirect URIs, refresh-token rotation or binding, and how access tokens are delivered to APIs.
Migration can be incremental. A deployment can continue to identify itself as OAuth 2.0 while following RFC 9700 today. In many cases that is more accurate than claiming OAuth 2.1 compliance early, because the OAuth 2.1 document is still an Internet-Draft and can change before final publication.
References
- IETF OAuth Working Group, The OAuth 2.1 Authorization Framework,
draft-ietf-oauth-v2-1-16, September 3, 2026: https://datatracker.ietf.org/doc/draft-ietf-oauth-v2-1/ - IETF / RFC Editor, RFC 9700: Best Current Practice for OAuth 2.0 Security, January 2025: https://www.rfc-editor.org/rfc/rfc9700.html
- IETF / RFC Editor, RFC 10017: OAuth 2.0 for Browser-Based Applications, August 2026: https://www.rfc-editor.org/rfc/rfc10017.html
- IETF / RFC Editor, RFC 6749: The OAuth 2.0 Authorization Framework, October 2012: https://www.rfc-editor.org/rfc/rfc6749.html
- IETF / RFC Editor, RFC 7636: Proof Key for Code Exchange by OAuth Public Clients, September 2015: https://www.rfc-editor.org/rfc/rfc7636.html