In this article
December 1, 2025
December 1, 2025

What is OAuth 2.0?

How modern apps get access to your data without your password.

OAuth 2.0 is everywhere: “Sign in with Google,” connecting your calendar to a productivity app, letting a GitHub integration read repos, or granting a CLI tool temporary access to your account. Despite that, it’s still one of the most misunderstood specs in modern software. This guide aims to make OAuth 2.0 feel obvious: what it is, why it exists, how the pieces fit, and how to implement it safely.

OAuth 2.0 in one sentence

OAuth 2.0 is an authorization framework that lets an application access a user’s data on another service without ever seeing the user’s password, by using short-lived tokens scoped to specific permissions.

A real-world example (the “calendar app” story)

Imagine you use a scheduling app called MeetMagic and it wants to read your Google Calendar so it can show your availability.

Without OAuth:

MeetMagic would have to ask for your Google password. You type it in, MeetMagic stores it, and now it can do anything your Google account can do. If MeetMagic gets hacked… so do you. Yikes.

With OAuth 2.0:

  1. In MeetMagic you click “Connect Google Calendar.”
  2. MeetMagic sends you to Google’s consent screen.
  3. Google shows a clear prompt like: “MeetMagic wants permission to:
    • View your calendars
    • See events (but not edit or delete anything).”
  4. You click Allow.
  5. Google sends MeetMagic a short-lived access token that basically means:
    “MeetMagic can read Maria’s calendar for the next hour.”
  6. MeetMagic uses that token to call the Google Calendar API.
  7. If you later disconnect MeetMagic in your Google account settings, the token stops working.

What matters here:

  • MeetMagic never sees your password.
  • The token is limited (read-only calendar access).
  • The token is temporary (expires soon).
  • You, the user, can revoke access anytime.

That’s OAuth 2.0: delegated, scoped, time-limited access instead of sharing credentials.

What OAuth 2.0 is (and isn’t)

OAuth 2.0 is authorization.

OAuth 2.0 answers: “Can this app do that thing with this user’s data?”

It adds an authorization layer separating the app (client) from the user (resource owner), and uses access tokens instead of passwords.

OAuth 2.0 is NOT authentication.

OAuth doesn’t tell you who the user is. It only tells you what an app is allowed to do.

If you want login + identity, that’s OpenID Connect (OIDC), which layers authentication on top of OAuth 2.0.

What OAuth 2.0 is used for

You reach for OAuth 2.0 when you need delegated access:

  • Third-party integrations: Your app reads a user’s Google Calendar only after they consent.
  • “Connect your account” flows: Slack, Notion, HubSpot, etc.
  • Mobile, SPA, and desktop apps that shouldn’t handle passwords directly.
  • Machine-to-machine access between backend services.

The core idea: tokens instead of passwords

OAuth replaces “share your password with an app” (yikes) with “share a token that does only what you approved, for only as long as needed.”

Token types:

  • Access token: A string, typically a JSON Web Token (JWT), that an app sends to another service in order to perform certain actions on behalf of the user. It’s typically short-lived (lasting only minutes). The service that receives an access token must validate it before allowing access, ensuring that the request is not attempting to perform actions that have not been authorized.
  • Refresh token: A long-lived credential (typically in the format of an opaque string) used to get new access tokens without re-prompting the user.

OAuth roles explained (with a quick mental model)

OAuth defines four roles:

  • Resource Owner
    • Usually the end user.
    • Owns the data.
  • Client
    • The app requesting access.
    • Example: a travel app that wants your Google Contacts.
  • Authorization Server
    • The system that authenticates the user and issues tokens.
    • Example: Google’s OAuth server or WorkOS.
  • Resource Server
    • The API holding the protected data.
    • Example: Google Contacts API.

The main OAuth 2.0 grants (flows)

OAuth supports multiple “grant types” because apps come in different shapes and sizes, and have different constraints and requirements. These are the ones you’ll see most:

1. Authorization Code (with or without PKCE): the default for user logins

The most common OAuth flow today is the Authorization Code flow. It’s the one behind things like “Connect your Google account” or “Allow this app to access your GitHub”.

At a high level, it works like this: the app sends the user to the provider’s authorization page, the user logs in and approves access, and the provider sends the app back a short-lived authorization code. The app then exchanges that code for an access token (and often a refresh token) using a secure, direct call to the provider.

Originally, this flow assumed the app could keep a private credential called a client secret: something only server-side apps can safely store. But many modern apps are “public clients,” like single-page apps (SPAs), mobile apps, and desktop apps. Those apps can’t reliably hide a secret, because their code runs on devices users control.

That’s where PKCE comes in. PKCE is a simple upgrade to the Authorization Code flow that proves the app starting the login is the same one finishing it, without relying on a hidden secret. It protects public clients from code interception attacks, and it’s now considered the standard way to use Authorization Code in browsers and native apps.

2. Client Credentials: machine-to-machine

Not every OAuth exchange involves a user. Sometimes one backend service needs to talk to another backend service, and the permissions are tied to the application itself, not a person. That’s the Client Credentials flow.

In this flow, the client authenticates directly with the authorization server and receives an access token that represents the client’s own identity and permissions. Since there’s no user consent step, it’s ideal for service-to-service calls like background jobs, internal microservices, or partner integrations where the “owner” of the data is the app or organization, not an individual user.

3. Device Code: for TVs, CLIs, IoT

Some devices can’t comfortably complete a browser-based login. Think smart TVs, game consoles, or command-line tools: they may not have a real browser, and typing a long password on them is painful. The Device Code flow exists for exactly that situation.

Here, the client asks the authorization server for a device code and a short, human-friendly user code. The device then shows the user something like: “Go to this URL and enter this code”. The user completes the login and consent on a separate, more convenient device (like their phone or laptop). Once that happens, the original device polls the authorization server and receives an access token.

From the user’s perspective, it feels like pairing a device. Under the hood, it’s OAuth adapted to constrained interfaces.

4. Refresh Token grant: silent re-auth

OAuth is designed around short-lived access tokens, which is great for security but annoying if the user had to approve access every hour. Refresh tokens solve that trade-off.

When the authorization server issues a refresh token alongside the access token, the client can later exchange that refresh token for a brand-new access token, without involving the user again. That lets an integration stay connected over time while still relying on short-lived access tokens for actual API calls.

You can think of refresh tokens as “permission to renew access,” and access tokens as “permission to act right now”.

Legacy flows you might hear about (but shouldn’t use)

OAuth 2.0 has a couple flows that were common years ago but are now considered outdated for most apps.

  • The Implicit flow was once used by browser-based apps, but it’s largely been replaced by Authorization Code with PKCE, because PKCE gives you the same usability with much stronger security.
  • The other one is Resource Owner Password Credentials (ROPC), where an app asks the user for their password and swaps it for a token. Even though the spec allows it, it defeats one of OAuth’s main goals (keeping passwords out of third-party apps) so it’s generally a last resort for legacy systems.

You should never use these flows for building something new, and if something already exists you should plan to migrate to another secure flow.

Security pitfalls (and how to avoid them)

OAuth is safe when implemented correctly. Most incidents come from a handful of repeat mistakes.

Common pitfalls

  • Not using PKCE for SPAs or mobile apps.
  • Storing tokens insecurely in browsers or logs.
  • Over-broad scopes (“request everything, just in case”).
  • Skipping audience/issuer checks on JWTs.
  • Long-lived access tokens without rotation.
  • Redirect URI mismatch vulnerabilities (open redirects).
  • Using legacy Implicit or ROPC flows.

Best practices

  • Prefer Authorization Code + PKCE for user flows.
  • Keep access tokens short-lived; use refresh tokens for continuity.
  • Always include a cryptographically random state parameter in authorization requests and verify it on return to prevent CSRF.
  • Enforce exact redirect URI matching (meaning only pre-registered full-string matches, with no wildcards or pattern matching).
  • Validate JWTs fully: signature, iss, aud, exp, and scopes.
  • Use least-privilege scopes and make consent screens clear.
  • Rotate refresh tokens and revoke on suspicious activity.
  • Separate auth server and resource server responsibilities cleanly.

OAuth 2.0 vs OAuth 2.1

You’ll increasingly hear OAuth 2.1. It’s essentially OAuth 2.0 with modern best practices baked in:

  • PKCE required
  • Implicit removed
  • ROPC discouraged
  • Better security defaults

OAuth 2.1 is still a draft specification (as of early 2025) and hasn't been formally ratified yet, but its recommendations are already considered best practice.

For more details, see OAuth 2.1: What’s new, what’s gone, and how to migrate securely.

How WorkOS solves OAuth for you

By now, OAuth 2.0 should feel a lot less mysterious: it’s a clean way to delegate access using scoped, short-lived tokens, and the main flows map neatly to real product needs.

But knowing what OAuth is and shipping a production-grade implementation are two different things.

The spec leaves room for interpretation, providers behave differently, edge cases pile up fast, and small mistakes around redirects, token storage, or consent can turn into real security incidents. In practice, most teams don’t struggle with the basics, they struggle with getting all the details right, everywhere, over time.

Implementing OAuth well is surprisingly hard:

  • picking the right flows
  • getting PKCE and refresh tokens right
  • safe consent UX
  • multi-tenant authorization
  • token security, revocation, rotation
  • supporting social providers and your own platform OAuth

WorkOS gives you a production-ready OAuth/OIDC layer without reinventing all that.

With WorkOS you get:

In short: WorkOS lets you offer secure “Sign in with X” and “Connect your account” experiences in days, not weeks, with the right defaults already in place.

The key takeaways

If you remember nothing else:

  • OAuth 2.0 is for authorization, not login.
  • It works by issuing scoped, time-limited tokens instead of sharing passwords.
  • Authorization Code + PKCE is the modern default.
  • Most OAuth failures are implementation mistakes, not spec issues.
  • Providers like WorkOS remove most of that complexity.

Final thoughts

OAuth 2.0 is the quiet workhorse behind modern apps: it makes integrations possible, keeps passwords out of places they don’t belong, and gives users fine-grained control over their data. Once you internalize the roles, tokens, and the handful of main flows, OAuth stops feeling mystical and starts feeling like a straightforward delegation protocol.

And if you don’t want to sweat every security nuance or keep up with evolving best practices, WorkOS can be your shortcut to an OAuth implementation that’s secure, scalable, and pleasant for developers and users alike.

Sign up today.

This site uses cookies to improve your experience. Please accept the use of cookies on this site. You can review our cookie policy here and our privacy policy here. If you choose to refuse, functionality of this site will be limited.