OAuth 2.0 vs OIDC: When to Use Each
Understanding the distinction between OAuth 2.0 and OpenID Connect (OIDC) is fundamental for designing secure and efficient authentication and…
Understanding the distinction between OAuth 2.0 and OpenID Connect (OIDC) is fundamental for designing secure and efficient authentication and authorization flows in modern applications. While often used together, they serve distinct purposes: OAuth 2.0 is an authorization framework, whereas OIDC is an identity layer built on top of OAuth 2.0. This article will dissect each protocol, illustrating their core functionalities, typical use cases, and how to determine which one (or both) your system requires.
OAuth 2.0: Authorization Delegation
OAuth 2.0, formalized in RFC 6749, is an authorization framework that enables a third-party application to obtain limited access to an HTTP service on behalf of a resource owner. It explicitly does not deal with authentication of the resource owner (the user) to the service provider; its sole purpose is to delegate authorization. Think of it as a valet key: you give it to a third party so they can access specific parts of your car (e.g., drive it) without giving them the master key that opens everything (e.g., the trunk).
Core Concepts
- Resource Owner: The entity (typically a user) who owns the protected resources and can grant access.
- Resource Server: The server hosting the protected resources (e.g., Google Calendar API, Facebook Graph API).
- Client: The application requesting access to the protected resources on behalf of the resource owner (e.g., a mobile app, a web application).
- Authorization Server: The server that authenticates the resource owner and issues access tokens after obtaining authorization (often the same as the Resource Server, but can be separate).
- Access Token: A credential used to access protected resources. It's typically a bearer token (anyone holding it can use it), opaque to the client, and has a limited lifespan and scope.
- Refresh Token: A long-lived credential used to obtain new access tokens without re-involving the resource owner.
- Scope: Defines the specific permissions requested by the client (e.g.,
read:calendar,write:email).
Typical OAuth 2.0 Flow (Authorization Code Grant)
# 1. Client directs resource owner to Authorization Server
GET https://auth.example.com/oauth/authorize?
response_type=code&
client_id=your_client_id&
redirect_uri=https://your-app.com/callback&
scope=read:calendar&
state=random_string_for_csrf_protection
# 2. Resource owner authenticates with Authorization Server and grants consent.
# 3. Authorization Server redirects resource owner back to Client with an authorization code.
GET https://your-app.com/callback?code=AUTH_CODE_FROM_SERVER&state=random_string_for_csrf_protection
# 4. Client exchanges authorization code for an access token (server-to-server).
POST https://auth.example.com/oauth/token
Content-Type: application/x-www-form-urlencoded
grant_type=authorization_code&
code=AUTH_CODE_FROM_SERVER&
redirect_uri=https://your-app.com/callback&
client_id=your_client_id&
client_secret=your_client_secret
# 5. Authorization Server responds with access token (and optionally a refresh token).
HTTP/1.1 200 OK
Content-Type: application/json
{
"access_token": "ACCESS_TOKEN_STRING",
"token_type": "Bearer",
"expires_in": 3600,
"refresh_token": "REFRESH_TOKEN_STRING",
"scope": "read:calendar"
}
# 6. Client uses access token to call Resource Server.
GET https://api.example.com/calendar/events
Authorization: Bearer ACCESS_TOKEN_STRING
OAuth 2.0 is ideal when your application needs to access specific resources on a user's behalf from another service, without needing to know the user's login credentials for that service. Examples include: a photo editor accessing your cloud photo library, a calendar app integrating with Google Calendar, or a social media manager posting to Twitter on your behalf.
OpenID Connect (OIDC): Identity Layer on OAuth 2.0
OpenID Connect (OIDC), specified in OpenID.org, is an identity layer built on top of the OAuth 2.0 framework. While OAuth 2.0 provides authorization, OIDC provides authentication. It allows clients to verify the identity of the end-user based on the authentication performed by an Authorization Server, as well as to obtain basic profile information about the end-user in an interoperable and REST-like manner.
Key Additions of OIDC to OAuth 2.0
- ID Token: A JSON Web Token (JWT) containing claims about the authentication event and the end-user. This is the core artifact of OIDC for identity verification.
- UserInfo Endpoint: An OAuth 2.0 protected resource endpoint that returns claims about the authenticated end-user.
- Standard Scopes: Defines standard scopes like
openid(mandatory for OIDC requests),profile,email,address, andphoneto request specific user information. - Discovery Endpoint: A standard endpoint (e.g.,
/.well-known/openid-configuration) that provides metadata about the OIDC provider, such as endpoint URLs, supported scopes, and public keys for ID Token verification.
OIDC Flow (Authorization Code Grant with ID Token)
The OIDC flow largely mirrors the OAuth 2.0 authorization code flow, with key differences in step 1 (scope=openid profile) and step 5 (the Authorization Server's response includes an id_token).
# 1. Client directs resource owner to Authorization Server (requesting OpenID and profile info)
GET https://auth.example.com/oauth/authorize?
response_type=code&
client_id=your_client_id&
redirect_uri=https://your-app.com/callback&
scope=openid profile email& <-- Crucial OIDC scopes
state=random_string_for_csrf_protection&
nonce=another_random_string_for_id_token_replay_protection
# ... Steps 2 & 3 are identical to OAuth 2.0 ...
# 4. Client exchanges authorization code for tokens (server-to-server).
POST https://auth.example.com/oauth/token
Content-Type: application/x-www-form-urlencoded
grant_type=authorization_code&
code=AUTH_CODE_FROM_SERVER&
redirect_uri=https://your-app.com/callback&
client_id=your_client_id&
client_secret=your_client_secret
# 5. Authorization Server responds with access token, refresh token, AND ID TOKEN.
HTTP/1.1 200 OK
Content-Type: application/json
{
"access_token": "ACCESS_TOKEN_STRING",
"token_type": "Bearer",
"expires_in": 3600,
"refresh_token": "REFRESH_TOKEN_STRING",
"id_token": "JWT_ID_TOKEN_STRING", <-- The identity assertion
"scope": "openid profile email"
}
The client must then validate the id_token. This involves verifying the signature (using the OIDC provider's public keys), checking the issuer (iss), audience (aud), expiration (exp), and comparing the nonce claim if one was sent in the initial request. Once validated, the claims within the ID Token (e.g., sub for subject, email, name) can be used to establish the user's identity within the client application.
When to Use Each
| Feature | OAuth 2.0 (Authorization) | OpenID Connect (Authentication) |
|---|---|---|
| Primary Goal | Granting delegated access to resources. | Verifying end-user identity and obtaining basic profile information. |
| Core Artifacts | Access Tokens, Refresh Tokens. | ID Tokens (JWTs), UserInfo Endpoint, Access Tokens. |
| What it provides | "This app can read your calendar." | "This user is Alice Smith (alice@example.com)." |
| Typical Use Cases |
|
|
| Client Knowledge | Doesn't need to know user's identity details. | Needs to parse and validate ID Token to assert user's identity. |
| Key Scopes | read:data, write:data, offline_access. |
openid (mandatory), profile, email, phone, address. |
Use OAuth 2.0 when:
- Your application needs to interact with a third-party API on behalf of a user (e.g., fetching emails, managing cloud storage, posting to social media).
- Your internal services need to securely communicate with each other, delegating specific permissions.
- The primary concern is granting specific, limited access to resources, not identifying the user to your application.
Use OIDC when:
- Your application needs to authenticate a user, confirming their identity.
- You want to implement Single Sign-On (SSO) across multiple applications, allowing users to log in once with an identity provider (IdP) and access various services without re-authenticating.
- Your application needs basic profile information about the user (e.g., name, email address) after they've logged in.
- You are building a client application (web, mobile, SPA) and require a secure way to know who the currently logged-in user is.
It's common for applications to use both. An OIDC flow will first authenticate the user and provide an ID Token. Simultaneously, it can provide an Access Token (via OAuth 2.0) that grants your application permission to access other APIs on the user's behalf. For instance, "Login with Google" uses OIDC to identify you, and then grants an OAuth 2.0 Access Token if you consent to a third-party app accessing your Google Calendar.
Common Pitfalls and Troubleshooting
- Confusing Authentication with Authorization: This is the most common mistake. OAuth 2.0 is NOT for authentication. Relying solely on an OAuth 2.0 access token to identify a user is a security vulnerability, as the access token only signifies permission, not identity. Always use an OIDC ID Token for identity verification.
- Insufficient ID Token Validation: Failing to properly validate all aspects of the ID Token (signature, issuer, audience, expiration, nonce) can lead to spoofed identities or replay attacks. Libraries like
python-joseorjwt-gogreatly simplify this, but ensure you understand the checks being performed. - Over-scoping: Requesting more permissions (scopes) than necessary in either OAuth 2.0 or OIDC. This reduces user trust and increases the attack surface. Only ask for what your application genuinely needs.
- Storing Secrets Insecurely: Client secrets for confidential clients (server-side web apps) must never be exposed to the client-side or public repositories. Public clients (SPAs, mobile apps) cannot keep secrets, hence rely on PKCE (Proof Key for Code Exchange) for authorization code grant security.
- Mismatched Redirect URIs: Ensure the
redirect_uriparameter sent in the authorization request precisely matches one pre-registered with the Authorization Server. Even a trailing slash can cause errors. - Ignoring
stateparameter: Thestateparameter is crucial for mitigating Cross-Site Request Forgery (CSRF) attacks. Always generate a cryptographically random state value for each request and verify it upon redirection. - Expired Tokens: Access tokens are short-lived. Implement robust refresh token mechanisms to obtain new access tokens without requiring the user to re-authenticate repeatedly. Handle expired refresh tokens by prompting the user for a full re-login.