KAHIBARO
Discord Login Register

13.11. OpenID Connect

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:

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:

In short:

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:

RoleDescription in OIDC context
End-UserThe 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 ServerWhere APIs live that are protected by access tokens. Often your backend API.

Your backend application is usually both:

ID Token

The most important thing OIDC adds is the ID Token.

An ID token:

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.

Example response:

json
{
  "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:

Scopes

OIDC defines some standard scopes to request specific pieces of identity data:

ScopeMeaning
openidRequired for any OIDC request. Turns OAuth into OIDC.
profileBasic profile info (name, family_name, given_name, etc.).
emailEmail and email_verified.
addressPostal address.
phonePhone number info.

If you do not include openid scope, you are using pure OAuth 2.0, not OpenID Connect.

Example scope string:

text
openid profile email

How OpenID Connect Extends OAuth 2.0

OpenID Connect does not replace OAuth 2.0. It reuses:

Then it adds:

Authorization Code Flow with OIDC

The most important OpenID Connect flow for web backends is:

The steps look very similar to OAuth 2.0, but with OIDC-specific details.

Step-by-step Flow

  1. User clicks “Login with X”

Your backend (or frontend) redirects the user to the OpenID Provider’s authorization endpoint:

Example URL (wrapped for readability):

text
   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.

  1. User logs in at the provider

The OpenID Provider shows its login page and authenticates the user.

  1. Provider redirects back with an authorization code

After successful login, the OP redirects to your redirect_uri:

text
   https://your-app.com/callback
     ?code=AUTHORIZATION_CODE
     &state=RANDOM_STRING
  1. Backend exchanges code for tokens

Your server sends a POST request to the OP’s token endpoint:

http
   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_VERIFIER

The response includes:

json
   {
     "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.

  1. Backend validates the ID token

Your backend must:

After validation, you can trust the sub and other user claims.

  1. Backend creates a local session or issues its own token

Common patterns:

  1. 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

StepOAuth 2.0 onlyOAuth 2.0 + OIDC
Authorization requestresponse_type=codeSame, but scope includes openid.
Tokens returnedAccess + optional refresh tokenAccess + ID token + optional refresh token.
Identity informationNot standardizedID 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

Typical ID token payload example:

json
{
  "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:

ClaimDescription
issIssuer, must match the provider’s URL.
subSubject, unique ID of the user at this provider.
audAudience, must include your client_id.
expExpiration time, in seconds since Unix epoch.
iatIssued-at time.
nonceOptional, 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

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

Example: Login with Google using OpenID Connect

Let us look at a concrete scenario that many backends implement: “Log in with Google”.

Assume:

1. Redirect User to Google

When the user clicks “Login with Google”, your backend sends them to:

text
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:

After acceptance, Google redirects to your callback:

text
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:

http
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_code

Google responds:

json
{
  "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:

  1. Decodes id_token as a JWT.
  2. Fetches Google’s public keys from the discovery document (more on that below).
  3. Verifies:
    • Signature.
    • iss is https://accounts.google.com or accounts.google.com.
    • aud is your client_id.
    • exp is not expired.

Then you read:

You can then:

5. (Optional) Call UserInfo Endpoint

You can also call Google’s UserInfo endpoint:

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

Google 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:

text
https://provider.com/.well-known/openid-configuration

This is a JSON document that describes:

Example (simplified):

json
{
  "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

In this pattern, the browser never sees the access or refresh tokens directly.

Pattern 2: SPA Frontend + Backend API

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

How OpenID Connect Works with Your Own Authentication

You might build both:

A common approach:

  1. For email/password:
    • Store hashed passwords.
    • Issue JWTs or session cookies.
  2. 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.
  3. 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.

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:

For backend development, OpenID Connect lets you:

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

Comments

Please login to add a comment.

Don't have an account? Register now!