Lab · 02 / 16
Access is not identity.
They are often used as synonyms, but they answer different questions. OAuth 2.0 lets an app act on your behalf. OpenID Connect, built on top of it, tells the app who you are.
In plain words OAuth is a valet key: it lets someone drive your car, but says nothing about who you are. OpenID Connect adds an ID card: proof of who just signed in.
| OAuth 2.0authorization | OpenID Connectauthentication | |
|---|---|---|
| Question it answers | What may this app do on my behalf? | Who is the user, and how did they sign in? |
| Standard | RFC 6749 (2012), a framework | OpenID Foundation (2014), a layer on top of OAuth 2.0 |
| Main token | Access token, format not defined by the spec | ID token, always a signed JWT |
| Who reads the token | The API (resource server) | The app that requested the login (client) |
| How you ask for it | Scopes such as invoices:read | The openid scope, plus profile and email |
| User information | Not standardized | Standard claims and a UserInfo endpoint |
| Discovery | Authorization server metadata (RFC 8414) | /.well-known/openid-configuration |
| Typical use | An app calling an API, a service calling a service | Sign-in and single sign-on for web and mobile apps |
When to use OAuth 2.0
Use OAuth 2.0 alone when there is no user to identify, or the app only needs to call an API: client credentials, delegated access to a calendar.
When to use OpenID Connect
Use OpenID Connect whenever an app needs to know who the user is. You still get an access token in the same flow.
The most common mistake
Using the access token as proof of login. It was issued for the API, not for the app, so the app cannot safely tell who it belongs to. The opposite is wrong too: an API must not accept an ID token as a bearer token.
Side by side
// Access token: for the API
{
"iss": "https://idp.example.com",
"sub": "248289761001",
"aud": "https://api.example.com",
"client_id": "web-app",
"scope": "invoices:read",
"exp": 1760000900
}// ID token: for the app
{
"iss": "https://idp.example.com",
"sub": "248289761001",
"aud": "web-app",
"auth_time": 1759999995,
"amr": ["pwd", "otp"],
"nonce": "n-0S6_WzA2Mj",
"email": "ada@example.com"
}