OpenID Connect
Proof of who the user is, signed and checkable by anyone. Built on the OAuth server.
OpenID Connect adds identity to OAuth. When a client asks for the openid scope, the token reply also carries an id_token: a signed statement saying who the user is. Any client can check it against the public key on /oauth/jwks.
Get an ID token
Authorize exactly like OAuth, but ask for the openid scope. The token reply then includes the ID token alongside the access and refresh tokens.
# 1. Authorize with scope=openid profile email (see OAuth 2.0 server)# 2. Swap the code — the reply now includes id_tokencurl -X POST http://localhost:4000/oauth/token \ -d grant_type=authorization_code \ -d code=CODE -d redirect_uri=myapp://callback \ -d client_id=mobile-app -d code_verifier=VERIFIER # Answer (shortened){ "access_token": "tok_...", "token_type": "Bearer", "expires_in": 3600, "scope": "openid profile email", "refresh_token": "tok_...", "id_token": "eyJhbGciOiJSUzI1NiIs..."}What is inside the ID token
A signed JWT, good for 1 hour. Which personal claims appear depends on the scope that was asked for.
isssubaudexp / iatnonceemailnameCheck it against JWKS
The public key lives on /oauth/jwks. Any client can fetch it and check the ID token signature — no shared secret needed.
curl http://localhost:4000/oauth/jwks # Answer (shortened){ "keys": [ { "kty": "RSA", "kid": "yatta-1", "alg": "RS256", "n": "....", "e": "AQAB" } ]}Userinfo
The same claims are also available as plain JSON, for a valid access token.
curl http://localhost:4000/oauth/userinfo \ -H "Authorization: Bearer ACCESS_TOKEN" # Answer — claims follow the scope, like the ID token{ "sub": "user_1", "email": "ada@example.com", "name": "Ada"}401 invalid_token403 insufficient_scopeDiscovery
Clients find every endpoint in one place, with no guessing.
curl http://localhost:4000/.well-known/openid-configuration # Answer{ "issuer": "http://localhost:4000", "authorization_endpoint": "http://localhost:4000/oauth/authorize", "token_endpoint": "http://localhost:4000/oauth/token", "userinfo_endpoint": "http://localhost:4000/oauth/userinfo", "jwks_uri": "http://localhost:4000/oauth/jwks", "response_types_supported": ["code"], "subject_types_supported": ["public"], "id_token_signing_alg_values_supported": ["RS256"], "scopes_supported": ["openid", "profile", "email"], "claims_supported": ["sub", "iss", "aud", "exp", "iat", "nonce", "email", "name"], "grant_types_supported": ["authorization_code", "client_credentials", "refresh_token"], "code_challenge_methods_supported": ["S256", "plain"]}