OAuth
OAuth 2.0 is an authorization framework that allows users to grant third-party applications limited access to their accounts on another service — without sharing their passwords. It's the protocol behind 'Login with Google' and 'Continue with GitHub'.
Explanation
OAuth separates authentication (who are you?) from authorization (what can you access?). In the OAuth Authorization Code flow — the standard for web apps — four parties interact: the resource owner (the user), the client (your app), the authorization server (Google, GitHub, Auth0), and the resource server (the API protecting the user's data). The flow: your app redirects the user to the authorization server with a client_id, requested scope (e.g., read:email, repos), and a redirect_uri. The user authenticates and approves the requested permissions. The authorization server redirects back to your redirect_uri with a one-time authorization code. Your server exchanges the code (plus client_secret) for an access token (and optionally a refresh token). You use the access token to call the resource server's API on behalf of the user. OpenID Connect (OIDC) is an identity layer on top of OAuth 2.0 that adds authentication: in addition to an access token, the authorization server returns an ID token (a JWT with user identity claims like email and name). "Login with Google" is OIDC, not OAuth alone. Common OAuth 2.0 grant types: Authorization Code (for web/mobile apps — most secure), Authorization Code with PKCE (Proof Key for Code Exchange — for SPAs and mobile apps without a secure client_secret), Client Credentials (server-to-server communication, no user involved), and Implicit (deprecated — insecure, don't use). Auth0, Clerk, Supabase Auth, and NextAuth.js are popular libraries that implement OAuth flows for you.
Code Example
javascript// OAuth 2.0 Authorization Code flow (conceptual)
// Step 1: Redirect user to authorization server
const authUrl = new URL('https://accounts.google.com/o/oauth2/v2/auth');
authUrl.searchParams.set('client_id', process.env.GOOGLE_CLIENT_ID);
authUrl.searchParams.set('redirect_uri', 'https://yourapp.com/callback');
authUrl.searchParams.set('response_type', 'code');
authUrl.searchParams.set('scope', 'openid email profile');
authUrl.searchParams.set('state', generateCSRFToken()); // CSRF protection
res.redirect(authUrl.toString());
// Step 2: Handle callback — exchange code for tokens
app.get('/callback', async (req, res) => {
const { code, state } = req.query;
verifyCSRFToken(state); // prevent CSRF
const tokenResponse = await fetch('https://oauth2.googleapis.com/token', {
method: 'POST',
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
body: new URLSearchParams({
code,
client_id: process.env.GOOGLE_CLIENT_ID,
client_secret: process.env.GOOGLE_CLIENT_SECRET,
redirect_uri: 'https://yourapp.com/callback',
grant_type: 'authorization_code',
}),
});
const { access_token, id_token } = await tokenResponse.json();
// Decode id_token to get user info (verify signature in production)
const userInfo = decodeJwt(id_token);
await findOrCreateUser(userInfo.email, userInfo.name);
// Create your own session...
});
Why It Matters for Engineers
OAuth is the standard for "Sign in with X" features and API integrations. Every time your app connects to GitHub to display repos, calls Stripe to process payments, or uses Google for SSO — that's OAuth. Knowing how the flow works lets you implement it correctly, debug auth errors ("invalid_grant", "redirect_uri_mismatch"), and choose the right grant type for your use case. Understanding OAuth also prevents common security mistakes in AI-generated auth code: using the implicit flow (deprecated), not validating the state parameter (CSRF vulnerability), storing client_secret in client-side code, and not verifying ID token signatures.
Learn This In Practice
Go deeper with the full module on Beyond Vibe Code.
Web Development Fundamentals → →