13.11. OpenID Connect
Table of Contents
Why OpenID Connect Exists
OpenID Connect (OIDC) is an authentication layer built on top of OAuth 2.0.
You already learned that OAuth 2.0 is mainly about authorization. It lets an application (the client) get permission to access some resources on behalf of a user, usually through access tokens.
However, OAuth 2.0 by itself does not clearly define:
- Who the user is.
- How to get the user’s profile information.
- How to safely represent the logged-in user in a standard way.
Different providers (Google, Facebook, GitHub) all invented their own solutions on top of OAuth. This led to confusion and many custom implementations.
OpenID Connect fixes this by defining:
- How to perform user login using OAuth 2.0.
- How to get a standard identity token that says who the user is.
- How to get standard user profile data.
In short:
- OAuth 2.0: “Can this app access this resource?”
- OpenID Connect: “Who is this user?” and “Log this user in.”
Key idea: OpenID Connect = OAuth 2.0 + a standard way to authenticate users and get their identity.
This is very useful for backend developers, because you can integrate with existing identity providers and avoid storing passwords yourself.
Core Concepts
To understand OpenID Connect, you need to recognize a few core building blocks.
Parties Involved
OIDC uses the same main roles as OAuth 2.0, but adds the idea of identity:
| Role | Description in OIDC context |
|---|---|
| End-User | The human who wants to log in. |
| Relying Party (RP) | Your application, which relies on OIDC to authenticate users. |
| OpenID Provider (OP) | The identity provider that authenticates users and issues tokens. Examples: Google, Auth0, Okta, Keycloak. |
| Resource Server | Where APIs live that are protected by access tokens. Often your backend API. |
Your backend application is usually both:
- A Relying Party for login.
- A Resource Server for its own API, which accepts access tokens.
ID Token
The most important thing OIDC adds is the ID Token.
An ID token:
- Is a JWT (JSON Web Token).
- Is issued by the OpenID Provider.
- Contains information about the user, for example:
sub(subject, unique user ID)nameemailpicture- Contains information about the token itself:
iss(issuer)aud(audience, who this token is for)exp(expiration time)iat(issued at)
Your backend uses the ID token to know who the user is.
Important: In OpenID Connect, authentication is represented by the ID token, not the access token.
Access tokens are still used to call APIs, but ID tokens are used to log the user in.
UserInfo Endpoint
OpenID Connect defines a standard UserInfo endpoint on the OpenID Provider.
- You call it with a valid access token.
- It returns a JSON object with user information:
subnameemail- Others, depending on the provider and scopes.
Example response:
{
"sub": "1234567890",
"name": "Alice Example",
"email": "alice@example.com",
"email_verified": true,
"picture": "https://example.com/avatar.png"
}You can use the ID token and UserInfo endpoint together:
- ID token: quick identity information, signed, can be validated without a network call.
- UserInfo: extra profile data, fetched on demand.
Scopes
OIDC defines some standard scopes to request specific pieces of identity data:
| Scope | Meaning |
|---|---|
openid | Required for any OIDC request. Turns OAuth into OIDC. |
profile | Basic profile info (name, family_name, given_name, etc.). |
email | Email and email_verified. |
address | Postal address. |
phone | Phone number info. |
If you do not include openid scope, you are using pure OAuth 2.0, not OpenID Connect.
Example scope string:
openid profile emailHow OpenID Connect Extends OAuth 2.0
OpenID Connect does not replace OAuth 2.0. It reuses:
- Authorization endpoints
- Token endpoints
- Redirect flows
- Access tokens
Then it adds:
- ID tokens
- Standard claims
- Standard endpoints (UserInfo, discovery)
- Security rules about how to use them
Authorization Code Flow with OIDC
The most important OpenID Connect flow for web backends is:
- Authorization Code Flow, often with PKCE for extra security.
The steps look very similar to OAuth 2.0, but with OIDC-specific details.
Step-by-step Flow
- User clicks “Login with X”
Your backend (or frontend) redirects the user to the OpenID Provider’s authorization endpoint:
Example URL (wrapped for readability):
https://accounts.example.com/authorize
?response_type=code
&client_id=YOUR_CLIENT_ID
&redirect_uri=https://your-app.com/callback
&scope=openid%20profile%20email
&state=RANDOM_STRING
&code_challenge=SOME_HASH
&code_challenge_method=S256
Key OIDC detail: scope includes openid.
- User logs in at the provider
The OpenID Provider shows its login page and authenticates the user.
- Provider redirects back with an authorization code
After successful login, the OP redirects to your redirect_uri:
https://your-app.com/callback
?code=AUTHORIZATION_CODE
&state=RANDOM_STRING- Backend exchanges code for tokens
Your server sends a POST request to the OP’s token endpoint:
POST /oauth/token
Content-Type: application/x-www-form-urlencoded
grant_type=authorization_code&
code=AUTHORIZATION_CODE&
redirect_uri=https://your-app.com/callback&
client_id=YOUR_CLIENT_ID&
client_secret=YOUR_CLIENT_SECRET&
code_verifier=ORIGINAL_CODE_VERIFIERThe response includes:
{
"access_token": "ACCESS_TOKEN_VALUE",
"id_token": "ID_TOKEN_JWT",
"token_type": "Bearer",
"expires_in": 3600,
"refresh_token": "REFRESH_TOKEN_VALUE"
}
OIDC addition: the id_token.
- Backend validates the ID token
Your backend must:
- Decode the JWT.
- Verify its signature using the OP’s public keys.
- Check important claims:
issmatches expected issuer.audcontains yourclient_id.expis in the future.nonceif you used it (mostly for browser-based apps).
After validation, you can trust the sub and other user claims.
- Backend creates a local session or issues its own token
Common patterns:
- Create a local user record (if it does not exist).
- Link the OIDC
subto your local user. - Create your own session cookie or JWT that your API will use.
- Using the access token
- If your backend also needs to call APIs protected by the OP, it uses the access token.
- To get more user profile data, call the UserInfo endpoint with the access token.
OIDC vs Bare OAuth 2.0 in the Flow
| Step | OAuth 2.0 only | OAuth 2.0 + OIDC |
|---|---|---|
| Authorization request | response_type=code | Same, but scope includes openid. |
| Tokens returned | Access + optional refresh token | Access + ID token + optional refresh token. |
| Identity information | Not standardized | ID token + UserInfo endpoint with standard claims. |
So OpenID Connect is really about giving authentication a formal, interoperable shape.
Tokens in OpenID Connect
OIDC involves different kinds of tokens. As a backend developer, you must understand how to use each correctly.
ID Token
- Format: JWT.
- Intended audience: the client (your app).
- Purpose: prove the identity of the user.
Typical ID token payload example:
{
"iss": "https://accounts.example.com",
"sub": "1234567890",
"aud": "your-client-id",
"exp": 1727700000,
"iat": 1727696400,
"nonce": "abc123nonce",
"name": "Alice Example",
"email": "alice@example.com",
"email_verified": true,
"picture": "https://example.com/avatar.png"
}Important claims:
| Claim | Description |
|---|---|
iss | Issuer, must match the provider’s URL. |
sub | Subject, unique ID of the user at this provider. |
aud | Audience, must include your client_id. |
exp | Expiration time, in seconds since Unix epoch. |
iat | Issued-at time. |
nonce | Optional, used mainly in browser-based flows to prevent replay. |
Rule: Never use the ID token to directly authorize access to protected resources. Use access tokens for API authorization. Use ID tokens for who the user is.
Access Token
- Possibly a JWT, but can be opaque (provider’s choice).
- Used to access APIs (resource servers).
- OIDC does not fully define its content, but defines how it is obtained.
Your backend validates the access token whenever a client calls your API. You learned how to handle JWTs in the tokens and JWT chapters.
Refresh Token
- Optional.
- Used by your backend to get new access tokens (and sometimes new ID tokens) from the token endpoint.
- Should be stored securely on the server side, not in the browser.
Example: Login with Google using OpenID Connect
Let us look at a concrete scenario that many backends implement: “Log in with Google”.
Assume:
- Your backend is at
https://myapp.com. - You registered an OAuth 2.0 / OIDC client at Google.
- You have:
client_idclient_secretredirect_uri=https://myapp.com/auth/google/callback
1. Redirect User to Google
When the user clicks “Login with Google”, your backend sends them to:
https://accounts.google.com/o/oauth2/v2/auth
?client_id=YOUR_CLIENT_ID
&redirect_uri=https://myapp.com/auth/google/callback
&response_type=code
&scope=openid%20profile%20email
&state=RANDOM_STATE
&access_type=offline
&prompt=consent
Key OIDC detail: scope=openid profile email.
2. User Logs in and Grants Access
Google shows:
- Login form (if not already logged in).
- Consent screen asking if your app can see basic profile and email.
After acceptance, Google redirects to your callback:
https://myapp.com/auth/google/callback
?code=AUTH_CODE
&state=RANDOM_STATE
You verify state to avoid CSRF attacks.
3. Exchange Code for Tokens
Your backend sends a POST request:
POST https://oauth2.googleapis.com/token
Content-Type: application/x-www-form-urlencoded
code=AUTH_CODE&
client_id=YOUR_CLIENT_ID&
client_secret=YOUR_CLIENT_SECRET&
redirect_uri=https://myapp.com/auth/google/callback&
grant_type=authorization_codeGoogle responds:
{
"access_token": "ACCESS_TOKEN",
"expires_in": 3599,
"refresh_token": "REFRESH_TOKEN",
"scope": "openid https://www.googleapis.com/auth/userinfo.profile https://www.googleapis.com/auth/userinfo.email",
"token_type": "Bearer",
"id_token": "JWT_ID_TOKEN"
}4. Decode and Verify the ID Token
Your backend:
- Decodes
id_tokenas a JWT. - Fetches Google’s public keys from the discovery document (more on that below).
- Verifies:
- Signature.
issishttps://accounts.google.comoraccounts.google.com.audis yourclient_id.expis not expired.
Then you read:
sub: Google user ID.email: user email.email_verified: whether email is verified.name,picture.
You can then:
- Create or find a local user record.
- Log them in by creating a local session cookie or your own JWT.
5. (Optional) Call UserInfo Endpoint
You can also call Google’s UserInfo endpoint:
GET https://openidconnect.googleapis.com/v1/userinfo
Authorization: Bearer ACCESS_TOKENGoogle returns JSON with standard OIDC claims.
Discovery and Configuration
One of the practical benefits of OpenID Connect is discovery.
An OpenID Provider usually exposes a well-known configuration endpoint:
https://provider.com/.well-known/openid-configurationThis is a JSON document that describes:
issuerauthorization_endpointtoken_endpointuserinfo_endpointjwks_uri(JSON Web Key Set, for verifying tokens)- supported scopes, response types, etc.
Example (simplified):
{
"issuer": "https://accounts.example.com",
"authorization_endpoint": "https://accounts.example.com/authorize",
"token_endpoint": "https://accounts.example.com/oauth/token",
"userinfo_endpoint": "https://accounts.example.com/userinfo",
"jwks_uri": "https://accounts.example.com/.well-known/jwks.json",
"response_types_supported": ["code", "id_token", "code id_token"],
"scopes_supported": ["openid", "profile", "email"]
}
The JWKS document at jwks_uri contains the public keys used to sign ID tokens. Your backend loads these keys and uses them to validate JWT signatures.
This makes it easier to work with multiple providers because your backend does not need manually configured public keys.
Typical Backend Patterns with OpenID Connect
As a backend developer, you will often use OIDC in one of these patterns.
Pattern 1: Backend-Rendered Web App with OIDC Login
- Your app renders HTML pages.
- Login button redirects to the OIDC provider.
- Callback handler exchanges code for tokens and creates a server-side session.
- Session ID is stored in a secure, HTTP-only cookie.
- Backend may also store:
- OIDC
sub - ID token (short lived)
- Refresh token (for API calls on the user’s behalf)
In this pattern, the browser never sees the access or refresh tokens directly.
Pattern 2: SPA Frontend + Backend API
- Frontend (SPA) uses OIDC flow in the browser.
- SPA gets ID token and access token.
- SPA calls your backend API with access token.
- Your backend validates the access token and authorizes the user.
There are more security details here, but the general idea is similar to using JWTs for authentication.
Pattern 3: Backend API protects endpoints with OIDC tokens
- Clients (mobile apps, SPAs, other servers) obtain OIDC tokens from the provider.
- They send access tokens to your API.
- Your API validates access tokens and extracts user information (like
sub,email,scope). - You map
subto your internal user and apply authorization.
How OpenID Connect Works with Your Own Authentication
You might build both:
- A local authentication system (email + password).
- OIDC logins (“Login with Google”, “Login with GitHub”).
A common approach:
- For email/password:
- Store hashed passwords.
- Issue JWTs or session cookies.
- For OIDC:
- Never store OIDC-provider passwords.
- Store only:
- Provider name (for example
google) - Provider
sub - Some basic profile data (email, name)
- Link to local user ID.
- When a user logs in with OIDC:
- Use
sub+ provider to find or create a local user. - Issue your own local tokens or sessions as usual.
The backend logic is then unified: all authenticated users have local user IDs, no matter how they logged in.
Important Security Considerations
OpenID Connect is powerful, but you must use it correctly.
- Always validate ID tokens:
- Check signature.
- Check
iss,aud, andexp. - Never trust unsigned or unverified tokens.
- Use
stateparameter to prevent CSRF in login flow. - Use HTTPS everywhere to protect tokens in transit.
- Do not store tokens in insecure places like localStorage for high security use cases without understanding the risks.
- Use PKCE in public clients (SPA, mobile) to protect authorization codes from being stolen.
Do not implement your own OpenID Connect server from scratch as a beginner. Use well-tested identity providers or libraries. Mistakes here often lead to serious security vulnerabilities.
Summary
OpenID Connect:
- Builds on top of OAuth 2.0.
- Adds a clear way to authenticate users.
- Gives you ID tokens that describe who the user is.
- Provides a standard UserInfo endpoint and scopes to get user data.
- Uses the standard OAuth 2.0 authorization code flow, with extra rules and fields.
For backend development, OpenID Connect lets you:
- Use external identity providers like Google, Auth0, Okta, or your company’s SSO.
- Avoid handling passwords directly for those logins.
- Integrate multiple login methods into a single user system in your application.
Later, when you build real projects, you will likely use libraries or frameworks that implement the OIDC details for you, but understanding these concepts helps you configure and debug those integrations correctly.
Views: 4
KAHIBARO