OpenID Connect (OIDC) Authentication Guide
OpenID Connect (OIDC) Authentication Guide#
A comprehensive guide to understanding OpenID Connect and how it builds on OAuth 2.0 to provide standardized authentication.
Table of Contents#
- What is OpenID Connect?
- OAuth 2.0 vs OpenID Connect
- How OpenID Connect Works
- ID Tokens Explained
- OIDC Scopes
- OIDC Endpoints
- Implementation Guide
- UserInfo Endpoint
- Token Validation
- Discovery & Configuration
- Security Considerations
- Common Providers
- Best Practices
- Troubleshooting
What is OpenID Connect?#
OpenID Connect (OIDC) is an identity layer built on top of OAuth 2.0. While OAuth 2.0 is designed for authorization (granting access to resources), OpenID Connect adds authentication (verifying user identity).
The Problem OIDC Solves#
Before OIDC, every OAuth provider had their own way of providing user identity:
typescriptWith OIDC, there's a standardized way:
typescriptKey Benefits#
- Standardization: Same flow for all OIDC-compliant providers
- Built-in user info: ID tokens contain user claims (no extra API call needed)
- Better security: Cryptographically signed tokens
- Industry standard: Widely adopted (Google, Microsoft, Apple, Okta, Auth0, etc.)
- Interoperability: Use any OIDC-certified library
OAuth 2.0 vs OpenID Connect#
Visual Comparison#
Side-by-Side Comparison#
| Aspect | OAuth 2.0 | OpenID Connect |
|---|---|---|
| Primary Purpose | Authorization | Authentication |
| Question Answered | "What can the user do?" | "Who is the user?" |
| Token Types | Access token only | Access token + ID token |
| User Info | Custom API endpoint | Standardized /userinfo endpoint |
| Scopes | Resource-specific (read:email, write:files) |
Identity-specific (openid, email, profile) |
| Token Format | Opaque string (can be anything) | ID token is always a JWT |
| User Claims | Varies by provider | Standardized claims (sub, email, name) |
| Use Cases | API access, delegated permissions | User login, SSO, identity verification |
| Specification | RFC 6749 | Built on OAuth 2.0 + OpenID spec |
Use Case Examples#
Use OAuth 2.0 when:
- Accessing a user's Google Drive files
- Posting to a user's Twitter account
- Reading a user's GitHub repositories
- Sending emails via Gmail API
Use OpenID Connect when:
- Logging users into your application
- Implementing Single Sign-On (SSO)
- Verifying user identity
- Getting user profile information
Use Both when:
- Sign in with Google AND access their calendar
- Sign in with GitHub AND read their repositories
- Sign in with Microsoft AND access OneDrive
How OpenID Connect Works#
The Complete OIDC Flow#
Step-by-Step Breakdown#
1. Authorization Request#
typescriptKey OIDC additions:
scopeincludesopenid(required for OIDC)nonceparameter for replay attack prevention
2. Token Exchange#
typescript3. Decode & Verify ID Token#
typescriptID Tokens Explained#
The ID token is the heart of OpenID Connect. It's a JSON Web Token (JWT) that contains identity information about the authenticated user.
Anatomy of an ID Token#
An ID token consists of three parts separated by dots:
textHeader#
jsonPayload (Claims)#
jsonSignature#
The signature ensures the token hasn't been tampered with:
textStandard Claims#
| Claim | Description | Example |
|---|---|---|
sub |
Subject - unique user identifier (NEVER changes) | "107265685217823649876" |
iss |
Issuer - who created the token | "https://accounts.google.com" |
aud |
Audience - who token is intended for | "your-client-id" |
exp |
Expiration time (Unix timestamp) | 1642602000 |
iat |
Issued at time (Unix timestamp) | 1642598400 |
nonce |
Random value to prevent replay attacks | "abc123xyz" |
auth_time |
When user authentication occurred | 1642598350 |
acr |
Authentication Context Class Reference | "urn:maa:loa:1" |
amr |
Authentication Methods References | ["pwd", "mfa"] |
Profile Claims#
Requested with scope=profile:
jsonEmail Claims#
Requested with scope=email:
jsonAddress Claims#
Requested with scope=address:
jsonOIDC Scopes#
OpenID Connect defines standard scopes that request specific sets of claims.
Required Scope#
typescriptWithout openid scope, it's just OAuth 2.0 (no ID token returned).
Standard Scopes#
typescriptCombining with OAuth Scopes#
You can mix OIDC scopes with provider-specific OAuth scopes:
typescriptOffline Access#
Request refresh token:
typescriptOIDC Endpoints#
OpenID Connect providers expose standard endpoints.
Discovery Endpoint#
The .well-known/openid-configuration endpoint returns all OIDC metadata:
typescriptCore Endpoints#
1. Authorization Endpoint#
textParameters:
client_id- Your application's client IDredirect_uri- Where to send user after authorizationresponse_type- Usuallycodescope- Must includeopenid+ other scopesstate- Random value for CSRF protectionnonce- Random value for token replay prevention
2. Token Endpoint#
textParameters:
code- Authorization code from callbackclient_id- Your application's client IDclient_secret- Your application's client secretredirect_uri- Must match authorization requestgrant_type-authorization_code
Response:
json3. UserInfo Endpoint#
textResponse:
json4. JWKs Endpoint#
textResponse:
jsonImplementation Guide#
Basic OIDC Implementation#
typescriptHandling Callback#
typescriptManual Implementation (Without Library)#
typescriptUserInfo Endpoint#
The UserInfo endpoint provides additional claims not included in the ID token.
When to Use UserInfo#
Use ID token when:
- You only need standard claims (sub, email, name)
- You want to minimize API calls
- Token size is acceptable
- Claims don't change frequently
Use UserInfo endpoint when:
- You need claims not in ID token
- You want the latest user information
- Token size is a concern
- You need custom claims specific to the provider
Making UserInfo Requests#
typescriptComparing ID Token vs UserInfo#
typescriptToken Validation#
Proper ID token validation is critical for security.
Validation Checklist#
typescriptUsing a Library#
typescriptDiscovery & Configuration#
OIDC providers publish their configuration at a well-known endpoint.
Discovery Document#
typescriptCommon Provider Discovery URLs#
typescriptCaching Discovery Documents#
typescriptSecurity Considerations#
1. Always Validate ID Tokens#
typescript2. Use Nonce for Replay Prevention#
typescript3. Use State for CSRF Protection#
typescript4. Implement Token Expiration#
typescript5. Secure Token Storage#
typescript6. Validate Issuer#
typescript7. Use PKCE for Public Clients#
For mobile apps or SPAs:
typescriptCommon Providers#
Google#
typescriptMicrosoft / Azure AD#
typescriptApple#
typescriptOkta#
typescriptAuth0#
typescriptBest Practices#
1. Use Discovery for Configuration#
typescript2. Request Minimal Scopes#
typescript3. Handle Token Refresh#
typescript4. Implement Logout#
typescript5. Validate All Claims#
typescriptTroubleshooting#
Common Issues#
Issue: "Invalid nonce"
textIssue: "Invalid signature"
textIssue: "Token expired"
textIssue: "Invalid issuer"
textIssue: No email in claims
textDebugging Tools#
typescriptResources#
Official Specifications#
Libraries#
- Node.js: openid-client
- Python: PyJWT, Authlib
- Java: Nimbus JOSE+JWT
- C#: IdentityModel
- Go: coreos/go-oidc
Testing Tools#
- jwt.io - Decode and verify JWT tokens
- OpenID Connect Debugger - Test OIDC flows
- OAuth2 Debugger - Debug OAuth/OIDC flows
Certification#
- OpenID Certified Implementations - List of certified libraries and providers
Summary#
OpenID Connect provides:
- Standardization: Common protocol across all providers
- ID Tokens: Cryptographically signed JWTs with user identity
- UserInfo Endpoint: Standardized API for user information
- Discovery: Auto-configuration via well-known endpoints
- Security: Built-in protections (nonce, state, signature verification)
Key Differences from OAuth 2.0#
- ✅ Includes
openidscope → triggers OIDC flow - ✅ Returns ID token (JWT) → contains user claims
- ✅ Standardized endpoints → same across providers
- ✅ Built-in identity verification → no custom userinfo endpoints
When to Use OIDC#
- User authentication / login
- Single Sign-On (SSO)
- Identity verification
- Getting user profile information
OpenID Connect = OAuth 2.0 + Identity Layer 🔐
Happy authenticating! 🎉