AlgoInsight

System Design

OAuth 2.0 Explained

Every time you click 'Log in with Google,' OAuth 2.0 is working behind the scenes - letting an app access part of your account without ever seeing your password. Here's how that actually works, demystified.

By Admin2026-06-1815 min readoauthauthenticationauthorizationsecuritysystem-designapi

You've done it a hundred times: an app asks "Log in with Google?" or "Connect your account," you click, a familiar consent screen appears, you approve, and suddenly the app has access to part of your account - your profile, your contacts, your files - without you ever giving that app your password. The framework making this possible is OAuth 2.0, and it's one of the most important and most misunderstood pieces of modern web security. This guide explains what OAuth 2.0 actually does, the flow behind "Log in with X," and the crucial distinction it's built on.

The problem OAuth solves

Start with the problem. Suppose a photo-printing app wants to access your Google Photos to print them. The naive solution would be to give the app your Google password. This is terrible: now the app has full access to your entire Google account (not just photos), forever, and you have to trust it with your actual password - which it could store, leak, or misuse. Sharing your password gives away far too much, irrevocably.

OAuth 2.0 solves this: it lets you grant an app limited access to specific parts of your account, without sharing your password, and revocably. The photo app gets permission to access only your photos, you never reveal your password to it, and you can revoke that access anytime. OAuth is the framework for delegated authorization - letting you delegate limited access to a third party, safely, without that third party ever becoming a holder of your actual credentials.

The four roles

OAuth involves four parties, and naming them makes the flow clear:

The whole dance is about the client getting permission, from you, via the authorization server, to access your data on the resource server - without the client ever seeing your credentials.

How it works: the authorization flow

Here's the core OAuth flow (the "authorization code" flow, the standard for web apps), step by step:

  1. Initiate. You click "Connect with Google" in the app (the client). The app redirects you to Google's authorization server.
  2. Authenticate and consent. At Google (not the app), you log in (if not already) and see a consent screen telling you exactly what the app is asking to access ("This app wants to view your photos"). You approve or deny. Crucially, you're entering your password at Google, never at the app.
  3. Authorization code. If you approve, Google redirects you back to the app with a temporary authorization code - a short-lived, one-time code representing your grant.
  4. Exchange for a token. The app sends this code (along with its own credentials proving it's the legitimate app) back to Google's authorization server, which exchanges it for an access token.
  5. Access the resource. The app uses the access token to make requests to the resource server (Google Photos' API). The token grants access to only what you consented to.

So the app ends up with an access token scoped to your photos - and never touched your password. You authenticated directly with Google; the app only ever received a code and then a token.

sequenceDiagram
    participant U as You (resource owner)
    participant C as App (client)
    participant A as Authorization server
    participant R as Resource server
    U->>C: Click "Connect with Google"
    C->>A: Redirect you to authorize
    U->>A: Log in + consent (at Google, not the app)
    A-->>C: Authorization code
    C->>A: Exchange code (+ app credentials) for token
    A-->>C: Access token
    C->>R: Request data with access token
    R-->>C: Your photos (only what you consented to)
This sequence diagram shows the OAuth authorization code flow. You click connect with Google in the app. The app redirects you to the authorization server, where you log in and consent - at Google, never giving your password to the app. Google sends the app a temporary authorization code. The app exchanges that code, along with its own credentials, for an access token. The app then uses the access token to request your data from the resource server, which returns only what you consented to share. Your password never reached the app.

Access tokens, scopes, and refresh tokens

A few concepts make OAuth's access control precise:

Together, scopes (limited permissions), short-lived access tokens (limited exposure), and refresh tokens (sustained-but-revocable access) give OAuth fine-grained, controllable delegation.

The crucial distinction: authorization vs. authentication

Here's the point that confuses almost everyone, and that signals real understanding when you get it right: OAuth 2.0 is an authorization framework, not an authentication one.

OAuth 2.0 is fundamentally about authorization - granting an app limited access to your resources. It was not originally designed to tell the app who you are. But "Log in with Google" is clearly about identity (authentication) - so what's going on?

The answer: "Log in with X" uses OpenID Connect (OIDC), a thin layer built on top of OAuth 2.0 that adds authentication. OIDC uses OAuth's flow but adds a standard way to convey who the user is (an identity token), turning OAuth's authorization machinery into a login mechanism. So when you "log in with Google," you're using OpenID Connect, which rides on OAuth 2.0. Knowing that OAuth is authorization, OIDC adds authentication, and "social login" is OIDC-on-OAuth is exactly the distinction that separates people who understand OAuth from people who've just used it.

Why the flow has two steps (code, then token)

A natural question: why the two-step dance - get a code first, then exchange it for a token? Why not just hand the app the access token directly? The answer reveals OAuth's security thinking.

The redirect back to the app travels through the user's browser, which is a less-secure channel - things passing through it (in the URL) can potentially be exposed (browser history, logs, referrer headers). So OAuth deliberately sends only a temporary, one-time authorization code through that browser redirect - not the actual access token. The code alone is useless to an attacker, because exchanging it for a token requires the app's own secret credentials, which the app sends directly to the authorization server over a secure back-channel, not through the browser.

So the two-step design means: even if someone intercepts the authorization code from the browser redirect, they can't use it without the app's secret, which never travels through the browser. The sensitive access token is only ever obtained through the secure direct exchange. This is a deliberate, elegant security measure - splitting the flow so the vulnerable browser channel only ever carries something useless on its own. Understanding why the code-then-token two-step exists (to keep the token off the insecure browser channel) marks real understanding of OAuth rather than memorized steps.

Different flows for different clients

OAuth 2.0 defines several flows (grant types) for different situations:

The detail to remember: the authorization code flow is the default and most secure for user-facing apps, and OAuth provides other flows for special cases (notably machine-to-machine via client credentials). You don't need every flow memorized, but knowing OAuth adapts to different client types - and that the authorization code flow (with PKCE for public clients) is the recommended standard - shows current understanding.

OAuth security considerations

OAuth is secure when implemented correctly, but there are real pitfalls:

These reinforce that OAuth's security comes from careful implementation of its details - which is why, like most security, the advice is to lean on established, audited tools rather than improvising.

A worked example: connecting a calendar app

To ground it all, walk through a concrete case. You sign up for a scheduling app and want it to see your Google Calendar. You click "Connect Google Calendar." The app (client) redirects you to Google (authorization server). At Google, you log in (your password goes to Google, never the app) and see a consent screen: "This app wants to view and manage your calendar." You approve. Google redirects you back to the app with an authorization code. The app's server quietly exchanges that code - plus its own app credentials - with Google for an access token (and a refresh token). Now the app uses the access token to call Google Calendar's API and read your events, limited to the calendar scope you approved. When the access token expires, the app uses the refresh token to get a new one without bothering you. And if you later change your mind, you revoke the app's access in your Google settings - instantly cutting it off, without changing your password.

Every OAuth concept appears in that flow: the four roles, the consent, the code-then-token exchange, scopes (calendar only), access and refresh tokens, and revocability. That single "Connect Google Calendar" click is the whole framework working - and the app never saw your password, got only the calendar access you allowed, and can be revoked anytime. That's delegated authorization delivering exactly what it promises.

Why OAuth matters

OAuth 2.0 is foundational to the modern web because it solves delegated access cleanly:

Interview: OAuth comes up in system design around authentication, authorization, and third-party integration. The strong answer explains the problem (granting limited access without sharing passwords), the flow (redirect to authorization server, consent, authorization code, exchange for access token, use token on resource server), and the concepts (scopes for limited permissions, short-lived access tokens, refresh tokens). The senior-level signal is the distinction: OAuth 2.0 is authorization, not authentication, and "Log in with X" actually uses OpenID Connect layered on top. Getting that right shows you understand OAuth deeply rather than just having clicked "Log in with Google."

The bottom line

OAuth 2.0 is a framework for delegated authorization - letting you grant an app limited, specific, revocable access to your resources without sharing your password. It involves four roles (you the resource owner, the client app, the authorization server, the resource server) and a flow where you authenticate and consent at the provider (never giving the app your password), the app receives an authorization code, exchanges it for an access token, and uses that token - scoped to only what you allowed - to access your data. Scopes limit permissions, short-lived access tokens limit exposure, and refresh tokens sustain access revocably.

The crucial distinction: OAuth is authorization, not authentication - and "Log in with X" uses OpenID Connect layered on top to add identity. Understand the flow and that distinction, and OAuth stops being the mysterious thing behind the consent screen.

The single idea to carry away: OAuth replaced "give the app your password" with "tell the provider what to allow, and the app gets a limited, revocable token instead of your credentials." Every piece of the framework - the redirect to the provider, the consent screen, the code-then-token exchange, the scopes, the refresh tokens, the revocability - serves that one goal of safe, limited, password-free delegation. Once you see the framework as the answer to "how do I let an app do some things on my behalf without handing it the keys to everything," the whole design makes sense. We cover authentication, authorization, and security across System Design Fundamentals.


Go deeper

More articles