Overview of OAuth 2.0 Flows

Ready to start learning? Individual Plans →Team Plans →

Picking the wrong OAuth 2.0 flow is how teams end up with exposed tokens, broken sign-ins, and API integrations that fail in production. The fix is not memorizing every grant type; it is matching the flow to the client type, trust model, and security requirements.

Quick Answer

OAuth 2.0 flows are different grant types used to let an application access an API on behalf of a user or itself. As of January 2026, the safest default for most apps is the authorization code flow with PKCE, while client credentials fits machine-to-machine access and device authorization fits constrained devices. OAuth handles authorization, not authentication, and OpenID Connect adds identity on top of it.

Quick Procedure

  1. Identify whether a user is present.
  2. Decide whether the client can keep a secret.
  3. Choose authorization code flow for browser, mobile, and most server-rendered apps.
  4. Add PKCE for public clients such as SPAs and mobile apps.
  5. Use client credentials for service-to-service access.
  6. Use device authorization for TVs, kiosks, and CLI tools.
  7. Validate redirect URIs, limit scopes, and keep tokens short-lived.
Primary TopicOAuth 2.0 Flows
Best Default FlowAuthorization code flow with PKCE as of January 2026
Best for Machine-to-MachineClient credentials flow as of January 2026
Best for Constrained DevicesDevice authorization flow as of January 2026
Legacy Flow to AvoidImplicit flow as of January 2026
Key Security ControlExact redirect URI validation and PKCE as of January 2026
Related Identity StandardOpenID Connect for authentication and identity claims as of January 2026

Introduction

OAuth 2.0 is a delegated Authorization Framework that lets an application access an API without collecting the user’s password. That sounds simple, but flow selection changes the security profile of the entire application.

Choose the wrong grant type and you may expose tokens in the browser, force users through unnecessary login steps, or make service integrations harder to secure and troubleshoot. Choose the right one and you reduce risk, improve usability, and make the integration easier to operate.

This guide explains how each major flow works, where it fits, what can go wrong, and how current guidance changes the decision. It also clears up the common confusion between authorization and authentication, then shows where OpenID Connect fits when you need identity claims instead of API access alone.

For current security guidance, start with the official documents from RFC 6749, RFC 7636, and the evolving OAuth work tracked by the OAuth 2.1 draft information. Those references matter because they reflect the direction modern implementations are taking.

Understanding the OAuth 2.0 Model

OAuth 2.0 works by separating the user, the app, and the API into distinct roles. The four core roles are the resource owner, client, authorization server, and resource server.

The resource owner is usually the end user, but not always. The client is the application requesting access, the authorization server issues tokens, and the resource server hosts the protected API. Many implementation mistakes happen when teams treat the client as the user, which leads to bad assumptions about trust and permissions.

A typical request starts with the client redirecting the user to the authorization server. The user signs in, approves scopes, and the authorization server sends the client an authorization code or token depending on the flow. The client then exchanges that code for an access token, which is presented to the resource server.

How scopes and consent shape access

Scopes define what the client can do after authorization, such as reading profile data or posting to a specific API. Consent is the user’s approval for those requested scopes, and overbroad scopes increase the blast radius if a token leaks.

OAuth is about delegated access, not blanket trust. If a scope is too broad, the problem is usually the application design, not the protocol.

That distinction is why least privilege matters. If a calendar app only needs read-only access, do not request write scopes just because they are convenient.

For practical definitions of the terms in this model, ITU Online IT Training’s glossary entries for OAuth 2.0 Flows, OAuth 2.0, and Authentication are useful reference points when explaining these roles to a team.

How OAuth 2.0 Tokens Work

Access tokens are short-lived credentials used to call APIs after authorization succeeds. They are usually short-lived because a stolen token is easier to abuse than a stolen password when it can be reused without interaction.

A refresh token lets the client obtain a new access token without forcing the user to log in again. That improves session continuity, but it also creates a higher-value secret that must be stored and rotated carefully.

Token security depends on three controls: scope, lifetime, and audience. Scope limits actions, lifetime limits reuse, and audience makes sure the token is only accepted by the intended resource server.

Access token Used to call APIs; should usually be short-lived as of January 2026.
Refresh token Used to get new access tokens; should be stored and rotated with extra care as of January 2026.

Bearer tokens are powerful because whoever holds the token can use it. That is convenient for APIs, but it means transport security, secure storage, and log hygiene are non-negotiable.

Practical handling varies by client type. Server-side apps can store refresh tokens in protected back-end storage, while browser-based apps need a much tighter approach because the browser is harder to trust. The Server-Side pattern remains the safer home for secrets whenever the architecture allows it.

Official guidance from RFC 6750 explains bearer token usage, while Microsoft’s implementation guidance on Microsoft Learn is useful when you need to map theory to a real identity platform.

How Does the Authorization Code Flow Work?

Authorization code flow is the preferred OAuth 2.0 flow for most browser-based, server-rendered, and mobile applications because it keeps the access token out of the front channel. The browser receives only an authorization code, and the code is exchanged for tokens through a protected back end or secure app component.

The standard sequence is straightforward. The user starts in the client, gets redirected to the authorization server, signs in, consents to scopes, returns with a code, and the client exchanges that code for tokens.

  1. Redirect the user to the authorization server. The client sends the user-agent to a sign-in page with a client ID, requested scopes, redirect URI, and state value. The state parameter helps protect against CSRF and request mix-up attacks.
  2. Authenticate and obtain consent. The authorization server validates the user and prompts for consent if needed. This is where the user sees exactly what access the app wants.
  3. Receive the authorization code. After approval, the browser is redirected back to the registered redirect URI with a short-lived code. The code itself is not the final token and should be treated as sensitive.
  4. Exchange the code for tokens. The client sends the code to the token endpoint, usually along with client authentication or PKCE proof. This exchange should happen over HTTPS only.
  5. Use the access token to call the API. The client presents the token to the resource server. If refresh tokens are issued, the client stores them in a protected location and rotates them as required.

This flow works best for SaaS dashboards, partner integrations, and apps that need delegated access to a user’s third-party account. It is also the cleanest model when you want the user to approve access without ever sharing a password with the application.

Warning

Unsafe redirect handling is one of the fastest ways to break authorization code flow security. If your app accepts loose redirect URIs, an attacker may steal the code and redeem it elsewhere.

Current guidance from RFC 9700 strengthens the case for code-based flows with PKCE and strict redirect validation. That is the direction teams should treat as the default as of January 2026.

What Is Authorization Code Flow with PKCE?

PKCE is a proof key mechanism that protects authorization code flow from intercepted authorization codes. It is now strongly recommended for public clients such as mobile apps, single-page applications, and desktop apps that cannot safely keep a client secret.

Here is how it works in practice. The client generates a random code verifier, derives a code challenge, and sends the challenge during the authorization request. Later, when it exchanges the code, it must present the original verifier.

That means an attacker who steals the authorization code still cannot redeem it without the verifier. This closes a common gap in browser-based and distributed client implementations.

Where PKCE matters most

  • Mobile apps that use an embedded browser or system browser for sign-in.
  • Single-page applications that run entirely in the browser and cannot protect a secret.
  • Desktop applications that need delegated access but live outside a controlled server environment.

PKCE does not replace authorization code flow. It strengthens it, and that distinction matters when teams are modernizing older integrations.

For implementation guidance, the official specification at RFC 7636 is still the canonical reference. Many organizations now treat PKCE as mandatory for public clients, not optional.

When Should You Use Client Credentials Flow?

Client credentials flow is used when no human user is involved and the application acts on its own behalf. This is the right choice for machine-to-machine access, backend services, job processors, and internal integrations.

In this flow, the client authenticates directly to the authorization server, usually with a client ID and secret or another client authentication method. The resulting token represents the application, not a user.

That difference is important. A service calling an internal billing API should not pretend to be a person, and a batch job should not inherit broad end-user permissions just to make implementation easier.

  • Internal APIs used by service layers inside a platform.
  • Scheduled sync jobs that pull data from another system every hour.
  • Backend integrations that process events, webhooks, or queue messages.
  • Automated service-to-service access between microservices.

Security here is about secret management and scope minimization. Store secrets in a vault, rotate them regularly, and issue the narrowest token permissions possible. If your architecture supports certificate-based or federated client authentication, that is often stronger than static secrets.

For vendor-side implementation guidance, official documentation from Microsoft Learn and AWS is often the best place to confirm how a platform expects service identities to be configured.

Why Is the Implicit Flow Being Phased Out?

Implicit flow was originally designed to get tokens to browser apps without a back-end code exchange. That seemed attractive when SPAs needed a fast path to API access, but it created too much exposure in the browser.

The main problem is that tokens could end up in places that are difficult to secure: browser memory, history fragments, logs, extensions, or injected scripts. Once a bearer token is exposed, the browser offers far fewer protection boundaries than a server-side exchange.

Modern guidance now favors authorization code flow with PKCE instead. That gives browser-based apps a better security posture without sacrificing usability.

Note

If an older single-page app still uses implicit-style patterns, treat migration as a security project, not just a code cleanup task. Token handling changes can affect logout, refresh behavior, and redirect logic.

Migration is often straightforward in concept but messy in implementation. You may need to rework redirect URIs, token storage, and session handling to support code flow and PKCE cleanly. The Migration process should be tested in staging with real identity flows before you switch users over.

Browser security recommendations from standards groups and platform vendors point in the same direction: keep tokens out of front-channel exposure wherever possible.

What Is the Resource Owner Password Credentials Flow?

Resource owner password credentials flow exchanges a user’s password directly for tokens. It is discouraged in modern systems because the application handles the password, which defeats the core benefit of delegated authorization.

There are narrow legacy cases where it still appears, usually in older trusted first-party applications that were built before safer options were available. Even there, it is increasingly hard to justify from a security and compliance perspective.

The risks are obvious. Collecting passwords in the app increases phishing exposure, encourages password reuse, and complicates auditing because the application becomes part of the credential path.

  • Credential capture risk increases when the app handles the user’s password directly.
  • Phishing resistance is weaker because users cannot rely on a trusted authorization server page.
  • Compliance burden rises because the app now touches highly sensitive secrets.

Safer alternatives are authorization code flow, federated sign-in, and identity federation patterns built on OpenID Connect. In new systems, this flow should generally be avoided.

For current security context, the IETF guidance in RFC 6749 and newer OAuth guidance should be read together, not in isolation.

How Does Device Authorization Flow Work?

Device authorization flow is designed for devices with limited input or no browser, such as smart TVs, kiosks, and command-line tools. It lets the user approve access on a separate device while the constrained device polls for completion.

The user sees a short code and a verification URL on the constrained device. They then open the URL on a phone or computer, sign in, enter the code, and approve the request.

This pattern is effective because it balances usability and security. The device never needs to collect a password, and the code expires if the approval window is missed.

Typical device flow sequence

  1. Request a device code. The client asks the authorization server for a device code, user code, verification URL, and polling interval.
  2. Show the code to the user. The constrained device displays the user code and URL in a way that is easy to transcribe.
  3. Approve on a separate device. The user opens the verification URL, signs in, and confirms the requested scopes.
  4. Poll for token issuance. The constrained device polls until the authorization server returns the access token or an error.
  5. Use the token normally. The device presents the token to the resource server and continues until expiry or revocation.

This flow is especially useful for consumer devices, shared environments, and command-line automation where embedded browser login would be awkward or insecure. For a real-world example, think about a smart TV app that needs to connect to a streaming account without asking the user to type a password with a remote control.

For implementation details, the official specification is documented in RFC 8628.

How Do OAuth 2.0 Flows Compare Side by Side?

OAuth 2.0 flows differ mainly by whether a user is present, whether the client can keep a secret, and whether tokens are issued directly or after a code exchange. That is the fastest way to choose the right one in practice.

Authorization code + PKCE Best for mobile apps, SPAs, and most web apps; stronger browser security as of January 2026.
Client credentials Best for service-to-service access; no user consent is involved.
Device authorization Best for TVs, kiosks, and CLI tools; handles limited input cleanly.
Implicit Legacy browser pattern; generally avoid for new work as of January 2026.
Password credentials Legacy and discouraged; should usually be replaced in new systems.

For browser apps and mobile apps, authorization code with PKCE is the safest default. For back-end integrations, client credentials is more appropriate because it models the application as the actor. For constrained devices, device authorization avoids brittle workarounds.

If you are deciding between options, ask these questions: Is a user present? Can the app protect a secret? Do you need delegated user access or application access? Those questions narrow the choice quickly and correctly.

What Security Risks Are Common Across OAuth 2.0 Implementations?

Most OAuth problems come from implementation flaws, not from the protocol itself. The same flow can be safe or risky depending on how the client handles redirects, tokens, secrets, and logs.

Redirect URI abuse happens when an app accepts loose or wildcard redirect destinations. Exact matching is critical because redirect abuse can send codes or tokens to a domain controlled by an attacker.

Authorization code interception and token replay are other common issues. A code or token that leaks through logs, proxies, browser history, or misconfigured front-end code can often be used immediately by whoever sees it.

  • CSRF can break the trust between the user’s action and the authorization response if state validation is missing.
  • Mix-up attacks can confuse clients that talk to multiple authorization servers without clear issuer validation.
  • Overbroad scopes increase damage when a token is stolen or misused.
  • Long-lived tokens give attackers more time to abuse compromised credentials.

Browser-based apps face additional storage risks. Local storage, query strings, and URL fragments are all places where tokens can leak accidentally. Secure handling means minimizing exposure, not hoping users never inspect the browser state.

For current threat modeling, the guidance in OAuth 2.0 Security Best Current Practice is especially relevant. NIST guidance on application security and identity controls also helps teams align implementation with broader security policy.

What Are the Best Practices for Securing OAuth 2.0 Flows?

Secure OAuth 2.0 starts with transport security, precise validation, and token minimization. HTTPS is mandatory for redirects, authorization requests, and token exchanges because bearer tokens are too sensitive to send over cleartext links.

Use short-lived access tokens and refresh tokens only where the client can protect them properly. Validate redirect URIs exactly, not loosely, and validate the state parameter on every browser-based authorization response.

PKCE should be standard for public clients. If the client cannot reliably store a secret, then do not pretend it can. Treat the client as public and design the flow accordingly.

  1. Use HTTPS everywhere. Protect authorization, token exchange, and API calls with TLS.
  2. Register exact redirect URIs. Do not allow wildcard or overly broad callback URLs.
  3. Apply PKCE where applicable. Use it for mobile apps, SPAs, and desktop clients.
  4. Minimize scopes. Request only the permissions the app truly needs.
  5. Rotate and protect secrets. Store them in a vault and rotate them on a schedule.
  6. Sanitize logs. Ensure authorization codes, access tokens, refresh tokens, and passwords never appear in observability tools.

Pro Tip

When teams troubleshoot OAuth failures, the most useful logs are usually the ones that confirm the flow step, client ID, redirect URI, and state value without exposing any token material.

For standards-based hardening, review CIS Benchmarks, the NIST security guidance, and vendor implementation notes from Microsoft, AWS, or Cisco depending on your platform.

OAuth 2.0 and OpenID Connect: What’s the Difference?

OAuth 2.0 is for authorization, while OpenID Connect adds authentication and identity claims. If the app needs to call an API on a user’s behalf, OAuth 2.0 is the core tool. If the app needs to sign the user in, OpenID Connect is the missing layer.

This distinction matters because many teams assume that receiving an access token means they know who the user is. That is not reliable. An access token grants access; it is not the same thing as an identity assertion.

Common login flows use OpenID Connect on top of OAuth 2.0, often with an ID token carrying user identity claims. That is normal, but the app must still keep the two concepts separate in design and code.

  • Use OAuth 2.0 when a client needs delegated API access.
  • Use OpenID Connect when a client needs user sign-in and identity verification.
  • Use both when the application needs login plus API access.

Confusing the two leads to bad product decisions, especially when teams try to treat API scopes as proof of identity. For official protocol definitions, OpenID Connect Core is the right reference.

What Are Real-World OAuth 2.0 Use Cases?

OAuth 2.0 flows map cleanly to real operational patterns. A SaaS dashboard that connects to a customer’s data source usually uses authorization code flow because a human grants access to a specific account.

A backend integration that synchronizes records between two internal systems usually uses client credentials flow because no user is present and the application itself is the actor. That keeps the security model cleaner and the permissions easier to audit.

A mobile app that accesses a third-party API should usually use authorization code flow with PKCE. The app cannot safely keep a secret, so PKCE provides the missing protection.

  • Multi-tenant SaaS: authorization code flow with strict scope control.
  • Partner API integration: authorization code or client credentials, depending on whether user consent is needed.
  • Background sync job: client credentials with rotation and least privilege.
  • Smart TV or CLI tool: device authorization flow for constrained input.

For API access scenarios, it is often useful to think in terms of application information and trust boundaries. If the app is acting for itself, use application permissions. If it is acting for a person, use delegated permissions.

Security research from OWASP and protocol analysis from RFC Editor are valuable when designing these integrations because they expose the failure modes that look harmless in development but cause incidents later.

How Is OAuth 2.0 Evolving?

OAuth 2.0 is evolving toward safer defaults, especially for browser apps and public clients. The biggest shift is away from legacy patterns like implicit flow and toward authorization code flow with PKCE as the standard baseline.

OAuth 2.1 is often referenced as the direction modern implementations are heading, even when a final published version is not the point of the discussion. The practical takeaway is simple: fewer ambiguous flows, stronger PKCE usage, and more explicit browser security expectations.

This matters operationally because OAuth is not a one-time setup. Teams need periodic reviews when client types change, APIs evolve, or browser security guidance shifts.

OAuth is not a “configure it once and forget it” control. It is a living integration surface that needs the same review discipline as any other identity system.

For organizations that manage many integrations, ongoing governance should include redirect URI audits, scope reviews, token lifetime checks, and secret rotation verification. The broader move across the industry is toward simpler, safer defaults that reduce the number of ways an integration can go wrong.

For vendor-agnostic status updates and implementation direction, the best references are the OAuth community materials at OAuth.net and standards-track drafts at the IETF Datatracker.

What Common OAuth 2.0 Mistakes Should You Avoid?

Some of the most expensive OAuth mistakes are also the most preventable. Storing tokens in insecure browser storage, exposing them in URLs, and logging them in observability tools are all avoidable with basic engineering discipline.

Weak client registration is another common problem. If a client can register arbitrary redirect URIs or use a shared secret poorly, the whole authorization model becomes much easier to abuse.

Refresh tokens also need careful handling. If they are not rotated, revoked properly, or isolated from lower-trust components, a breach can persist much longer than it should.

  1. Do not store tokens in unsafe browser locations. Avoid query strings, fragments, and careless local storage use.
  2. Do not skip state validation. State helps defend browser redirects against CSRF-style abuse.
  3. Do not allow loose redirect URIs. Match callback URLs exactly.
  4. Do not over-privilege scopes. Request the smallest useful permission set.
  5. Do not leak secrets to logs. Scrub access tokens, refresh tokens, codes, and passwords from telemetry.

Legacy integrations deserve special attention because they often survive unchanged long after security guidance has moved on. A quick audit of token handling, redirect validation, and scope design can eliminate a large share of risk without changing the business logic.

For workforce and governance framing, the NICE Framework is useful for mapping OAuth responsibilities to identity, security, and application roles inside the organization.

Key Takeaway

  • Authorization code flow with PKCE is the safest default for most user-facing apps as of January 2026.
  • Client credentials flow is the right fit for machine-to-machine access with no user present.
  • Device authorization flow solves constrained-input scenarios like TVs, kiosks, and CLI tools.
  • Implicit flow and resource owner password credentials are legacy patterns that should generally be avoided in new systems.
  • OAuth 2.0 is authorization, not authentication; use OpenID Connect when the app needs identity claims.

Conclusion

The purpose of OAuth 2.0 flows is to choose the safest path for a specific application and trust model. The right answer depends on whether a user is involved, whether the client can protect a secret, and whether the device can support a normal browser-based exchange.

For most modern applications, the default choices are clear: authorization code flow with PKCE for user-facing apps, client credentials for service-to-service access, and device authorization for constrained devices. Keep tokens short-lived, validate redirects exactly, and request only the scopes you truly need.

Remember the most common mistake: OAuth 2.0 is not authentication. When you need sign-in and identity claims, pair OAuth with OpenID Connect instead of trying to force one protocol to do both jobs.

If you are maintaining an existing integration, review it against current security guidance, current redirect handling, and current token storage practices. ITU Online IT Training recommends treating OAuth reviews as part of routine identity and access governance, not as a one-time implementation task.

CompTIA®, Microsoft®, AWS®, Cisco®, and OpenID Connect are trademarks of their respective owners.

[ FAQ ]

Frequently Asked Questions.

What are the main differences between OAuth 2.0 authorization flows?

OAuth 2.0 offers several authorization flows, each designed for different client types and security needs. The main flows include Authorization Code, Implicit, Client Credentials, and Resource Owner Password Credentials.

The Authorization Code flow is suitable for server-side applications, providing high security by exchanging an authorization code for tokens. The Implicit flow is tailored for browser-based apps, but it has lower security and is being phased out in favor of Authorization Code with PKCE. Client Credentials is used for server-to-server communication, where no user context is needed. Resource Owner Password Credentials allows direct exchange of user credentials but is less recommended due to security concerns.

Which OAuth 2.0 flow should I use for a single-page application (SPA)?

For single-page applications, the recommended OAuth 2.0 flow is the Authorization Code flow with Proof Key for Code Exchange (PKCE). This flow enhances security by preventing authorization code interception attacks.

Unlike the Implicit flow, which was previously used for SPAs, Authorization Code with PKCE provides better security guarantees, especially since SPAs run in browsers and are more vulnerable to certain attacks. Implementing PKCE involves generating a code verifier and challenge during the authorization process, ensuring that tokens are securely obtained and exchanged.

Why is the Authorization Code flow with PKCE considered the safest default for most applications?

The Authorization Code flow with PKCE is considered the safest default because it mitigates common security vulnerabilities such as authorization code interception and CSRF attacks. PKCE adds an extra layer of security by requiring the client to generate a unique code verifier and challenge during the authorization process.

This flow is suitable for both confidential and public clients, including mobile and SPA apps, because it does not expose tokens in URLs or rely solely on client secrets. As a result, it reduces the risk of token leakage and ensures secure token exchange, making it the preferred standard as of January 2026.

What are common mistakes to avoid when choosing an OAuth 2.0 flow?

One common mistake is selecting a flow that does not match the client type or security requirements, such as using the Implicit flow for server-side apps or the Client Credentials flow for user-based access. This mismatch can lead to token exposure or broken sign-in processes.

Another mistake is not implementing additional security measures like PKCE with public clients or failing to validate redirect URIs properly. It’s also important to avoid using deprecated flows and to stay updated with best practices recommended by OAuth 2.0 standards to ensure secure and reliable API integrations.

How do OAuth 2.0 flows support different trust models?

OAuth 2.0 flows are designed to align with various trust models by controlling where and how tokens are issued and used. For example, the Authorization Code flow is suitable for high-trust applications like server-side apps, where secret management and secure exchanges are possible.

In contrast, flows like Implicit or PKCE are optimized for public clients, such as mobile or browser-based apps, where secrets cannot be securely stored. These flows minimize risk by limiting token exposure and enforcing strict validation measures, ensuring that applications operate within their trust boundaries while maintaining security integrity.

Related Articles

Ready to start learning? Individual Plans →Team Plans →
Discover More, Learn More
What Is Access Control Discover the fundamentals of access control and learn how regulating user and… What Is Access Control List (ACL) Discover how access control lists help enforce security by managing permissions effectively… What Is Access Control Matrix Discover how an access control matrix clarifies permissions, enhances security audits, and… What Is Access Control Systems Learn the fundamentals of access control systems and how they safeguard spaces… What Is Access Management Discover essential insights into access management and learn how to secure digital… What Is Access Point (AP) Explore what an access point is and how it enhances Wi-Fi coverage…
FREE COURSE OFFERS