OAuth 2.0 and OpenID Connect: A Practical Guide
OAuth 2.0 and OpenID Connect are foundational to modern authentication, and they're also some of the most misunderstood technologies in web development. After implementing auth systems across dozens of applications, here's the practical knowledge that matters.
OAuth 2.0 is about authorization, granting limited access to resources. OpenID Connect (OIDC) is a layer on top that adds authentication, verifying who a user is. When people say 'OAuth login,' they usually mean OIDC. The distinction matters because it determines which tokens you use and how you validate them.
The Authorization Code flow with PKCE is the correct choice for virtually every modern application, web apps, mobile apps, SPAs. The implicit flow is deprecated. The password grant is deprecated. If someone tells you to use either of these, push back. PKCE (Proof Key for Code Exchange) prevents authorization code interception attacks and works without a client secret, making it safe for public clients.
Tokens come in three flavors. The access token grants API access, it's short-lived (minutes to hours) and should never be stored in localStorage. The refresh token gets new access tokens, it's long-lived and must be stored securely (HttpOnly cookie or OS keychain). The ID token proves who the user is, it's a JWT containing user claims. Validate it on receipt, extract claims, then you can discard it.
JWT validation is critical and frequently done wrong. Verify the signature using the provider's public keys (fetched from the JWKS endpoint). Check the expiration (exp claim). Verify the audience (aud claim) matches your client ID. Verify the issuer (iss claim) matches your provider. Skip any of these checks and you have a security vulnerability.
For server-rendered applications like Next.js, the Auth0 SDK handles the heavy lifting. It manages the authorization code flow, stores tokens in encrypted HttpOnly cookies, provides session management, and handles token refresh transparently. Don't build this yourself unless you have a very specific reason.
RBAC (Role-Based Access Control) builds on top of OIDC. Assign roles in your identity provider, include them as custom claims in the ID token, and check them in your application's authorization layer. Auth0's RBAC system lets you define permissions at the API level and assign them to roles, which are assigned to users.
The security checklist: always use HTTPS, always use HttpOnly cookies for token storage, always validate tokens on the server side, never expose client secrets in frontend code, always use PKCE, and rotate signing keys periodically. These aren't optional.
Multi-tenant applications add complexity. Each tenant might use a different identity provider, one uses Google Workspace, another uses Azure AD, a third uses username/password. Protocols like SAML and OIDC provide a standard interface across these providers. Auth0's Enterprise Connections handle this federation transparently.