OAuth (Open Authorization)

The "Login with Google" button that lets apps access your stuff without your password.

5 min read

What is OAuth?

OAuth is an authorization framework that lets users grant apps access to their data on other services—without giving away their passwords. When you click "Sign in with Google" or "Connect to GitHub," OAuth is handling that handshake.

The magic: you authenticate with the service you trust (Google, GitHub, etc.), and they give the third-party app a token. The app never sees your password.

OAuth 2.0 is the current version. OAuth 1.0 still exists in legacy systems but is rarely used for new projects.

The OAuth 2.0 Flow (Simplified)

┌──────────┐                              ┌──────────────┐
│   User   │                              │  Auth Server │
│ (You)    │                              │  (Google)    │
└────┬─────┘                              └──────┬───────┘
     │                                           │
     │  1. Click "Login with Google"             │
     │ ─────────────────────────────────────────>│
     │                                           │
     │  2. "Do you authorize this app?"          │
     │ <─────────────────────────────────────────│
     │                                           │
     │  3. User clicks "Allow"                   │
     │ ─────────────────────────────────────────>│
     │                                           │
     │  4. Redirect with authorization code      │
     │ <─────────────────────────────────────────│
     │                                           │
     │     ┌─────────┐                           │
     │     │  App    │  5. Exchange code         │
     │     │ Backend │     for access token      │
     │     └────┬────┴──────────────────────────>│
     │          │                                │
     │          │  6. Access token returned      │
     │          │<───────────────────────────────│
     │          │                                │
     │          │  7. Use token to access API    │
     │          │───────────────────────────────>│

Key Concepts

TermWhat It Is
Resource OwnerThe user who owns the data
ClientThe app requesting access
Authorization ServerIssues tokens (Google, GitHub, etc.)
Resource ServerHolds the protected data (often same as auth server)
Access TokenShort-lived token to access resources
Refresh TokenLong-lived token to get new access tokens
ScopeWhat permissions the app is requesting

Grant Types

OAuth 2.0 has several "flows" for different scenarios:

Grant TypeUse CaseSecurity
Authorization CodeWeb apps with backendMost secure
Authorization Code + PKCEMobile/SPA appsSecure for public clients
Client CredentialsServer-to-serverNo user involved
Device CodeTVs, CLI toolsLimited input devices
Implicit (deprecated)SPAs without backendDon't use this anymore

Authorization Code Flow (The Common One)

Step 1: Redirect to authorization

https://accounts.google.com/oauth/authorize?
  client_id=YOUR_CLIENT_ID
  &redirect_uri=https://yourapp.com/callback
  &response_type=code
  &scope=email profile
  &state=random_csrf_token

Step 2: User authorizes, gets redirected back

https://yourapp.com/callback?
  code=AUTHORIZATION_CODE
  &state=random_csrf_token

Step 3: Exchange code for token (backend)

javascript
const response = await fetch('https://oauth2.googleapis.com/token', {
  method: 'POST',
  headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
  body: new URLSearchParams({
    code: 'AUTHORIZATION_CODE',
    client_id: 'YOUR_CLIENT_ID',
    client_secret: 'YOUR_CLIENT_SECRET',
    redirect_uri: 'https://yourapp.com/callback',
    grant_type: 'authorization_code'
  })
});

const { access_token, refresh_token, expires_in } = await response.json();

Step 4: Use the token

javascript
const user = await fetch('https://www.googleapis.com/oauth2/v2/userinfo', {
  headers: { Authorization: `Bearer ${access_token}` }
});

Where You'll See This

  • Social login - "Sign in with Google/GitHub/Apple"
  • Third-party integrations - Connecting Slack, Notion, or Figma to your app
  • API access - Accessing user data from other platforms
  • Single sign-on (SSO) - Enterprise identity providers
  • Mobile apps - Authenticating without storing passwords

OAuth vs OpenID Connect

OAuth is for authorization (what can you access). OpenID Connect (OIDC) is a layer on top for authentication (who are you).

OAuth 2.0OpenID Connect
PurposeAuthorizationAuthentication
TokenAccess tokenID token (JWT)
User infoSeparate API callIn the token
Use case"Access my files""Log me in"

When you click "Login with Google," you're typically using OIDC (which uses OAuth under the hood).

Common Gotchas

⚠️Never Expose Client Secret

Your client_secret must stay on the server. Never put it in frontend JavaScript, mobile apps, or commit it to git. That's why SPAs use PKCE instead.

  • Access tokens expire - Usually in 1 hour. Use refresh tokens to get new ones without re-authenticating.
  • Refresh tokens can be revoked - Don't assume they last forever.
  • State parameter is critical - It prevents CSRF attacks. Always validate it matches what you sent.
  • Scopes are case-sensitive - email is not Email.
  • Implicit flow is deprecated - If you see response_type=token, that's the old insecure way. Use Authorization Code + PKCE instead.
ℹ️PKCE for Public Clients

For SPAs and mobile apps, use PKCE (Proof Key for Code Exchange). It protects the authorization code from interception without needing a client secret.

Security Checklist

  1. Always use HTTPS
  2. Validate the state parameter
  3. Store tokens securely (not localStorage for sensitive apps)
  4. Use short-lived access tokens + refresh tokens
  5. Implement token revocation
  6. Validate redirect URIs strictly
  7. Use PKCE for mobile/SPA apps

Token Storage

StorageAccess TokenRefresh TokenNotes
MemoryGoodNoLost on refresh
HttpOnly CookieBestBestCSRF protection needed
localStorageRiskyNeverXSS vulnerable
sessionStorageOKNoTab-specific

Try It

Decode OAuth ID Tokens (JWTs)

"OAuth: Because 'just give me your password' wasn't going to fly in a security review."