Authorization is not authentication
OAuth 2.0 answers "is this app allowed to access that resource on the user's behalf". It is an authorization protocol, and it deliberately says nothing standard about who the user is. Apps tried to repurpose it for login anyway, in incompatible and sometimes insecure ways. OpenID Connect (OIDC) is the standard that fixes this: a thin identity layer on top of OAuth 2.0 that adds authentication without throwing away anything OAuth already does.
The ID token
The defining addition is the ID token, and it is a JWT. Where an OAuth access token is meant for an API and is often opaque to the client, the ID token is meant for the client and carries standard claims about the authenticated user:
iss(issuer) andaud(audience, the client it was issued for)sub(the stable, unique user identifier)expandiat(expiry and issued-at)nonce(binds the token to the specific login request, defeating replay)- profile claims such as
name,email, andpicturewhen those scopes are granted
Because it is a JWT, the client verifies the ID token's signature and validates those claims exactly as described for any JWT. The same pinning and aud/iss/exp checks apply.
How a login flows
OIDC reuses OAuth's machinery. The recommended flow is the authorization code flow with PKCE:
- The app sends the user to the provider's authorization endpoint, requesting the
openidscope (plusprofile,email, and so on), and includes a PKCEcode_challenge. - The user authenticates and consents at the provider.
- The app receives a one-time code, and exchanges it (proving possession of the PKCE
code_verifier) for an ID token and an access token. - The app verifies the ID token to establish who the user is, and uses the access token to call APIs on their behalf.
Two endpoints round it out: a userinfo endpoint returns profile claims for a valid access token, and a discovery document at /.well-known/openid-configuration advertises the provider's endpoints and its JWKS URL, so a client can find the keys to verify ID tokens and follow key rotation automatically.
Why it matters
OIDC is what most "Sign in with ..." buttons actually run on. Keeping the two tokens straight is the key insight: the ID token proves identity to the client, the access token authorizes API calls, and they are not interchangeable. Combined with the code flow and PKCE, it is the modern, standards-based way to do federated login.
The PKCE tool generates and verifies the code_verifier and code_challenge for the flow, and the JWT tool decodes and verifies the ID token, both entirely in your browser with nothing sent anywhere.