OpenID Connect

An authentication layer built on top of OAuth 2.0. OAuth answers “what can this app access?”; OIDC answers “who is this user?

What OIDC Adds to OAuth 2.0

FeatureOAuth 2.0OIDC
PurposeAuthorizationAuthentication + Authorization
Tokens issuedAccess tokenAccess token + ID Token
User identityNot standardizedStandardized via ID Token claims
User info endpointNone/userinfo returning standard claims
DiscoveryNone.well-known/openid-configuration
Standard scopesProvider-definedopenid, profile, email, phone, address

Triggering an OIDC Flow

Add the openid scope to an OAuth 2.0 Authorization Code Flow request. That’s it. The auth server now also returns an ID Token alongside the access token.

&scope=openid%20email%20profile

Without openid, you have OAuth — no identity, just an opaque “this client is allowed to call these APIs” token.

Standard Scopes and What They Return

ScopeReturns
openidRequired. Triggers OIDC. Returns sub (user identifier).
emailemail, email_verified
profilename, given_name, family_name, picture, locale, updated_at, etc.
phonephone_number, phone_number_verified
addressaddress (a structured object)

Discovery

OIDC providers publish a discovery document at:

https://{issuer}/.well-known/openid-configuration

It contains every endpoint URL, supported scopes, supported signing algorithms, and the JWKS URI for fetching public keys. Always discover at runtime rather than hardcoding endpoint URLs — providers occasionally rotate them.

{
  "issuer": "https://accounts.google.com",
  "authorization_endpoint": "https://accounts.google.com/o/oauth2/v2/auth",
  "token_endpoint": "https://oauth2.googleapis.com/token",
  "userinfo_endpoint": "https://openidconnect.googleapis.com/v1/userinfo",
  "jwks_uri": "https://www.googleapis.com/oauth2/v3/certs",
  "response_types_supported": ["code", "token", "id_token", "code token", "code id_token", "token id_token", "code token id_token"],
  "subject_types_supported": ["public"],
  "id_token_signing_alg_values_supported": ["RS256"],
  "scopes_supported": ["openid", "email", "profile"],
  ...
}

The UserInfo Endpoint

GET https://openidconnect.googleapis.com/v1/userinfo
Authorization: Bearer ACCESS_TOKEN

Returns standardized user claims (the same kind found in the ID Token). Useful when you need fresh data — the ID Token is a snapshot at login time.

Flow Variants

OIDC defines several flows; for web/mobile you almost always want the Authorization Code Flow (with PKCE).

  • Authorization Code Flow — code in front-channel, tokens in back-channel. Default choice.
  • Implicit Flow — tokens directly in front-channel. Deprecated.
  • Hybrid Flow — code + (id_token or token) in front-channel; remaining tokens in back-channel. Used by Sign in with Apple when name/email scopes are requested.

Pitfalls

  • Treating an OAuth-only access token as identity. Without openid scope and an ID Token, you have authorization, not authentication.
  • Trusting the UserInfo endpoint without validating the access token first. A compromised access token still calls UserInfo successfully.
  • Hardcoding endpoint URLs instead of using discovery → silent breakage on provider changes.

See Also