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
| Term | What It Is |
|---|---|
| Resource Owner | The user who owns the data |
| Client | The app requesting access |
| Authorization Server | Issues tokens (Google, GitHub, etc.) |
| Resource Server | Holds the protected data (often same as auth server) |
| Access Token | Short-lived token to access resources |
| Refresh Token | Long-lived token to get new access tokens |
| Scope | What permissions the app is requesting |
Grant Types
OAuth 2.0 has several "flows" for different scenarios:
| Grant Type | Use Case | Security |
|---|---|---|
| Authorization Code | Web apps with backend | Most secure |
| Authorization Code + PKCE | Mobile/SPA apps | Secure for public clients |
| Client Credentials | Server-to-server | No user involved |
| Device Code | TVs, CLI tools | Limited input devices |
| Implicit (deprecated) | SPAs without backend | Don'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)
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
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.0 | OpenID Connect | |
|---|---|---|
| Purpose | Authorization | Authentication |
| Token | Access token | ID token (JWT) |
| User info | Separate API call | In 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
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 -
emailis notEmail. - Implicit flow is deprecated - If you see
response_type=token, that's the old insecure way. Use Authorization Code + PKCE instead.
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
- Always use HTTPS
- Validate the
stateparameter - Store tokens securely (not localStorage for sensitive apps)
- Use short-lived access tokens + refresh tokens
- Implement token revocation
- Validate redirect URIs strictly
- Use PKCE for mobile/SPA apps
Token Storage
| Storage | Access Token | Refresh Token | Notes |
|---|---|---|---|
| Memory | Good | No | Lost on refresh |
| HttpOnly Cookie | Best | Best | CSRF protection needed |
| localStorage | Risky | Never | XSS vulnerable |
| sessionStorage | OK | No | Tab-specific |
Try It
Decode OAuth ID Tokens (JWTs)"OAuth: Because 'just give me your password' wasn't going to fly in a security review."