OpenID Connect vs OAuth 2.0: What Developers Actually Need to Know

OAuth 2.0 and OpenID Connect are often used together, but they solve different problems. Learn the practical difference between authorization, authentication, access tokens, ID tokens, scopes, and user identity.

BlitzWare Engineering - 2026-06-28

OAuth 2.0 and OpenID Connect are often mentioned together.

That makes sense because they are related.

But they are not the same thing.

The simplest way to remember the difference is this:

OAuth 2.0 is for authorization.
OpenID Connect is for authentication.

OAuth 2.0 answers:

Can this application access this API?

OpenID Connect answers:

Who is the user that signed in?

In real applications, you usually need both.

If you’re building a SaaS dashboard, mobile app, API platform, developer portal, internal tool, or single page application, this distinction matters. Misunderstanding it can lead to broken login flows, insecure API authorization, incorrect token validation, and confusing architecture decisions.

This guide explains the practical difference between OAuth 2.0 and OpenID Connect from a developer’s point of view.


The 30-second summary

Technology What it is What it solves
OAuth 2.0 Authorization framework Lets applications access protected resources
OpenID Connect Identity layer on top of OAuth 2.0 Lets applications authenticate users and receive identity information

OAuth 2.0 gives you access tokens.

OpenID Connect adds ID tokens.

OAuth 2.0 is about access.

OpenID Connect is about identity.

If your application needs to call an API, you need OAuth 2.0.

If your application needs to know who the user is, you likely need OpenID Connect.

Most modern login systems use OpenID Connect on top of OAuth 2.0.


A simple analogy

Imagine an office building.

OAuth 2.0 is like an access badge.

The badge says:

This person or application can enter Room A and Room B.

It does not necessarily explain who the person is in detail. It is mainly about access to resources.

OpenID Connect is like checking someone’s identity at the front desk.

The front desk says:

This person is Jane Developer.
Their email is [email protected].
They authenticated successfully.

OAuth 2.0 gives access.

OpenID Connect gives identity.

In a real system, you often use both:

Authenticate the user with OpenID Connect.
Authorize API access with OAuth 2.0.

What OAuth 2.0 actually does

OAuth 2.0 is an authorization framework.

It lets an application obtain limited access to a protected resource.

A protected resource is usually an API.

For example:

A frontend application wants to call your backend API.
A mobile app wants to read a user's profile.
A third-party integration wants access to a customer's workspace.
A CLI tool wants to manage resources through your API.

OAuth 2.0 defines how the application gets an access token.

The application then sends that access token to the API.

Example API request:

GET /api/projects
Authorization: Bearer eyJhbGciOiJSUzI1NiIs...

The API validates the access token and decides whether the request is allowed.

OAuth 2.0 focuses on questions like:

  • Which client is requesting access?
  • Which resource is being accessed?
  • Which scopes were granted?
  • How long should the token be valid?
  • Can this token be used for this API?
  • Should this request be allowed?

OAuth 2.0 does not define a standard way to log users in.

OAuth 2.0 does not define a standard identity token.

OAuth 2.0 does not define a standard user profile format.

That is where OpenID Connect comes in.


What OpenID Connect actually does

OpenID Connect, often shortened to OIDC, is an identity layer built on top of OAuth 2.0.

It adds a standardized way to authenticate users and communicate information about them.

The most important thing OpenID Connect adds is the ID token.

An ID token is usually a JWT that tells the client application who authenticated.

Example ID token payload:

{
  "iss": "https://auth.example.com",
  "sub": "user_123",
  "aud": "client_456",
  "exp": 1793200000,
  "iat": 1793196400,
  "email": "[email protected]",
  "email_verified": true,
  "name": "Jane Developer"
}

This token is meant for the client application.

It helps the application answer:

Who signed in?
When did they authenticate?
Which authorization server authenticated them?
Which client was this identity token issued for?
What basic identity claims are available?

OpenID Connect also defines standard scopes such as:

openid
profile
email
phone
address

The openid scope is what tells the authorization server that the application is requesting OpenID Connect behavior.

Without openid, you are usually doing OAuth 2.0 only.

With openid, you are asking for authentication and identity information.


OAuth 2.0 vs OpenID Connect in one flow

A modern login flow often uses both OAuth 2.0 and OpenID Connect.

Example authorization request:

https://auth.example.com/oauth/authorize?
  response_type=code&
  client_id=client_123&
  redirect_uri=https://app.example.com/callback&
  scope=openid profile email api.read&
  state=random_state&
  code_challenge=pkce_challenge&
  code_challenge_method=S256

Notice the scope:

openid profile email api.read

This includes both identity and API access.

Scope Meaning
openid Request OpenID Connect authentication
profile Request basic profile claims
email Request email-related claims
api.read Request API access

After the user authenticates, the application exchanges an authorization code for tokens.

Example token response:

{
  "access_token": "eyJhbGciOiJSUzI1NiIs...",
  "id_token": "eyJhbGciOiJSUzI1NiIs...",
  "token_type": "Bearer",
  "expires_in": 900,
  "scope": "openid profile email api.read"
}

This response may include:

Token Comes from Used for
Access token OAuth 2.0 Calling APIs
ID token OpenID Connect Identifying the authenticated user
Refresh token OAuth 2.0 extension behavior Getting new access tokens

The access token goes to your API.

The ID token is for your application.

Do not treat them as interchangeable.


Access token vs ID token

This is one of the most important distinctions.

Access token

An access token is used to access an API.

Example:

GET /api/projects
Authorization: Bearer <access_token>

The API validates the access token.

The API should check things like:

  • Signature
  • Issuer
  • Audience
  • Expiration
  • Scopes
  • Token type
  • Subject
  • Client ID

The access token answers:

Is this request allowed to access this API?

ID token

An ID token is used by the client application to understand the authenticated user.

Example:

{
  "sub": "user_123",
  "email": "[email protected]",
  "name": "Jane Developer"
}

The ID token answers:

Who signed in?

The ID token should usually not be sent to your API as the authorization credential.

Your API should receive an access token.

Your frontend or application client receives and validates the ID token for login state and identity purposes.


Why this distinction matters

If you use the wrong token in the wrong place, your architecture becomes weaker.

Bad pattern:

Frontend logs in with OIDC.
Frontend receives ID token.
Frontend sends ID token to API.
API accepts ID token as proof of API access.

This is a common mistake.

An ID token is not designed to represent API permissions.

A better pattern:

Frontend logs in with OIDC.
Frontend receives ID token for user identity.
Frontend receives access token for API access.
Frontend sends access token to API.
API validates access token and scopes.

This keeps identity and authorization separate.

That separation makes your system easier to secure, debug, and scale.


What about “Login with Google”?

When developers say “OAuth login,” they often mean “login with Google,” “login with Discord,” or “login with GitHub.”

Technically, many modern social login flows are OpenID Connect or OAuth-based flows.

For example, when an application offers “Sign in with Google,” the application often uses OpenID Connect to get an ID token that proves who the user is.

The user experience is:

Click "Sign in with Google"
Authenticate with Google
Return to the application
Application knows who the user is

From the user’s perspective, it is login.

From the protocol perspective, OpenID Connect is usually the part that standardizes identity.

OAuth 2.0 may still be involved underneath because OpenID Connect is built on OAuth 2.0.

That is why people often mix the terms.

The practical developer rule is:

If you need user login, use OpenID Connect.
If you need API access, use OAuth 2.0 access tokens.
If you need both, use OpenID Connect with OAuth scopes.

Token comparison

Token Standardized by Audience Main purpose
Access token OAuth 2.0 API / resource server Authorize API access
ID token OpenID Connect Client application Prove user authentication
Refresh token OAuth 2.0 Client / authorization server Obtain new access tokens

The most common mistake is sending the ID token to the API and treating it as an access token.

The second most common mistake is using an access token as the application’s user profile.

Keep them separate.


The role of scopes

Scopes are often used in both OAuth 2.0 and OpenID Connect.

But they mean different things depending on what you request.

OAuth API scopes

OAuth scopes describe API permissions.

Examples:

projects:read
projects:write
billing:read
users:manage

These are useful for backend authorization.

Example:

This token can read projects but cannot delete them.

OpenID Connect scopes

OpenID Connect scopes describe identity information being requested.

Examples:

openid
profile
email
phone
address

These are useful for login and user identity.

Example:

This application wants to know the user's email address.

A combined request might look like this:

openid profile email projects:read projects:write

That means:

Authenticate the user.
Return basic identity information.
Grant access to read and write projects.

The openid scope is special

The openid scope is what turns an OAuth authorization request into an OpenID Connect request.

Without it:

scope=api.read

You are asking for OAuth API access.

With it:

scope=openid profile email api.read

You are asking for OpenID Connect authentication plus OAuth API access.

If you expect an ID token but forget the openid scope, your authorization server may not return one.

If your app only needs API access and not user identity, you may not need OpenID Connect at all.

But if your app needs login, the openid scope is usually required.


The UserInfo endpoint

OpenID Connect also defines a UserInfo endpoint.

The client can call it with an access token to retrieve user claims.

Example:

GET /userinfo
Authorization: Bearer <access_token>

Example response:

{
  "sub": "user_123",
  "email": "[email protected]",
  "email_verified": true,
  "name": "Jane Developer"
}

The UserInfo endpoint is useful when:

  • You do not want many claims inside the ID token.
  • You want to fetch profile information separately.
  • You want a standard way to retrieve user claims.
  • The client needs updated user profile data.

The ID token proves authentication.

The UserInfo endpoint can provide additional user claims.


Real-world example: SaaS dashboard

Imagine you are building a SaaS dashboard.

Users log in and manage projects.

You need to know who the user is.

You also need to call your backend API.

A good flow:

1. User clicks "Log in".
2. App redirects to authorization server.
3. User authenticates.
4. App receives authorization code.
5. App exchanges code for tokens.
6. App receives ID token and access token.
7. App uses ID token to understand login identity.
8. App uses access token to call the API.
9. API validates access token and checks scopes.

Example ID token:

{
  "sub": "user_123",
  "email": "[email protected]",
  "name": "Jane Developer",
  "aud": "client_abc"
}

Example access token:

{
  "sub": "user_123",
  "aud": "https://api.example.com",
  "scope": "projects:read projects:write",
  "client_id": "client_abc"
}

The ID token is for the app.

The access token is for the API.

The sub value may identify the same user, but the tokens serve different purposes.


Real-world example: machine-to-machine API access

Now imagine there is no user.

A backend service needs to call another backend service.

Example:

Billing service needs to call Reporting API.

In this case, OpenID Connect is usually not needed because there is no user to authenticate.

You need OAuth 2.0 client credentials.

Flow:

1. Service authenticates as a client.
2. Authorization server issues access token.
3. Service calls API with access token.
4. API validates token and scopes.

Example token payload:

{
  "iss": "https://auth.example.com",
  "sub": "client_billing_service",
  "aud": "https://reporting-api.example.com",
  "scope": "reports:write",
  "client_id": "billing_service"
}

No ID token is required.

OAuth 2.0 alone is enough.


Real-world example: third-party integration

Imagine your product allows customers to connect a third-party app.

The third-party app needs access to the customer’s resources.

Example:

A customer grants an external analytics tool access to read project data.

This is classic OAuth 2.0.

The important question is not just “who is the user?”

The important question is:

Did the customer authorize this client to access this resource with these scopes?

The result is an access token with limited permissions.

Example:

{
  "sub": "user_123",
  "client_id": "external_analytics_app",
  "aud": "https://api.example.com",
  "scope": "projects:read analytics:read",
  "exp": 1793200000
}

OpenID Connect may be used to authenticate the user during the flow, but OAuth 2.0 is what handles delegated API access.


Authentication vs authorization

The words are similar, but the difference matters.

Authentication means:

Who are you?

Authorization means:

What are you allowed to access?

OpenID Connect helps with authentication.

OAuth 2.0 helps with authorization.

A user can be authenticated but not authorized.

Example:

Jane is logged in.
Jane is not allowed to access the billing settings.

A service can be authorized without representing a human user.

Example:

The deployment service can write deployment logs.
No human user is involved.

Good systems separate these concepts clearly.


Should your app use OAuth 2.0, OpenID Connect, or both?

Use this decision table.

Your use case What you need
Users log into your app OpenID Connect
Your frontend calls your API OAuth 2.0 access tokens
Your app needs both login and API access OpenID Connect + OAuth 2.0
Service-to-service API access OAuth 2.0 client credentials
Third-party integrations OAuth 2.0 authorization
Social login Usually OpenID Connect or provider-specific OAuth
User profile claims OpenID Connect
API permissions and scopes OAuth 2.0

Most SaaS applications need both.

Most APIs need OAuth 2.0.

Most login experiences should use OpenID Connect.


How access tokens should be validated

Your API should validate access tokens strictly.

For JWT access tokens, check:

  • Signature
  • Issuer
  • Audience
  • Expiration
  • Not-before time
  • Algorithm
  • Key ID
  • Token type
  • Scopes
  • Subject
  • Client ID
  • Revocation status if supported

Example Express middleware:

import type { Request, Response, NextFunction } from "express";
import { createRemoteJWKSet, jwtVerify } from "jose";

const issuer = "https://auth.example.com";
const audience = "https://api.example.com";
const jwks = createRemoteJWKSet(new URL(`${issuer}/.well-known/jwks.json`));

export async function authenticateApiRequest(
  req: Request,
  res: Response,
  next: NextFunction
) {
  const header = req.headers.authorization;

  if (!header?.startsWith("Bearer ")) {
    return res.status(401).json({
      error: "Missing access token.",
    });
  }

  const token = header.slice("Bearer ".length);

  try {
    const { payload } = await jwtVerify(token, jwks, {
      issuer,
      audience,
      algorithms: ["RS256", "ES256"],
      clockTolerance: "30s",
    });

    req.auth = {
      subject: payload.sub,
      clientId: payload.client_id,
      scope: typeof payload.scope === "string" ? payload.scope : "",
    };

    next();
  } catch {
    return res.status(401).json({
      error: "Invalid or expired access token.",
    });
  }
}

Then enforce scopes:

export function requireScope(requiredScope: string) {
  return (req: Request, res: Response, next: NextFunction) => {
    const scopes = new Set((req.auth?.scope ?? "").split(" ").filter(Boolean));

    if (!scopes.has(requiredScope)) {
      return res.status(403).json({
        error: "Insufficient permissions.",
      });
    }

    next();
  };
}

Usage:

app.get(
  "/api/projects",
  authenticateApiRequest,
  requireScope("projects:read"),
  async (req, res) => {
    res.json({
      projects: [],
    });
  }
);

Your API should not trust the frontend.

Your API should not accept a token just because it can be decoded.

Your API should validate the access token every time.


How ID tokens should be validated

A client application that receives an ID token should also validate it.

For an ID token, check:

  • Signature
  • Issuer
  • Audience
  • Expiration
  • Nonce, when used
  • Subject
  • Authorized party, when relevant
  • Authentication time, when required

The most important difference is the audience.

For an ID token, the audience is usually the client application.

For an access token, the audience is usually the API.

Example ID token:

{
  "iss": "https://auth.example.com",
  "sub": "user_123",
  "aud": "client_abc",
  "exp": 1793200000,
  "iat": 1793196400,
  "nonce": "random_nonce"
}

Example access token:

{
  "iss": "https://auth.example.com",
  "sub": "user_123",
  "aud": "https://api.example.com",
  "exp": 1793200000,
  "iat": 1793196400,
  "scope": "projects:read"
}

If your API expects audience:

https://api.example.com

it should reject a token whose audience is:

client_abc

That is one reason APIs should not accept ID tokens as access tokens.


Common misconceptions

Misconception 1: OAuth 2.0 is a login protocol

OAuth 2.0 alone is not a complete login protocol.

It is an authorization framework.

You can build login-like behavior with OAuth 2.0, and many providers historically did, but OpenID Connect was created to standardize authentication and identity on top of OAuth 2.0.

For modern applications, use OpenID Connect when you need login.


Misconception 2: If I have an access token, I know who the user is

Maybe, but not always.

An access token may represent:

  • A user
  • A service account
  • A machine client
  • A delegated authorization
  • A technical integration

The sub claim can identify a subject, but the token’s main purpose is API access.

If your application needs a standardized user identity for login, use OpenID Connect.


Misconception 3: ID tokens are for APIs

ID tokens are for client applications.

APIs should normally receive access tokens.

If an API accepts ID tokens, it can accidentally bypass scope checks, audience validation, and resource-specific authorization rules.

Use the right token for the right job.


Misconception 4: OpenID Connect replaces OAuth 2.0

OpenID Connect does not replace OAuth 2.0.

It extends it.

OpenID Connect uses OAuth 2.0 flows and adds identity features.

That is why a modern login flow can return both an ID token and an access token.


Misconception 5: JWT means OpenID Connect

JWT is a token format.

OAuth 2.0 access tokens can be JWTs.

OpenID Connect ID tokens are usually JWTs.

But JWT itself is not OAuth and not OpenID Connect.

A JWT can be used for many different purposes.

Always validate what kind of JWT it is and what it is meant for.


Common security mistakes

Avoid these mistakes:

  • Sending ID tokens to APIs as access tokens.
  • Accepting tokens without validating the audience.
  • Accepting tokens without validating the issuer.
  • Decoding JWTs without verifying signatures.
  • Using OAuth 2.0 alone as a login protocol when OpenID Connect is needed.
  • Forgetting the openid scope.
  • Treating frontend checks as authorization.
  • Giving access tokens overly broad scopes.
  • Putting too much personal data inside tokens.
  • Logging tokens.
  • Using long-lived access tokens in browser apps.
  • Shipping client secrets in frontend code.
  • Using the Implicit Flow for new browser-based applications.
  • Ignoring PKCE for public clients.
  • Confusing authentication with authorization.

Most OAuth and OpenID Connect bugs come from unclear boundaries.

Know which token is for which audience and which purpose.


Practical architecture patterns

SPA with API backend

Use:

OpenID Connect for login
OAuth 2.0 access tokens for API calls
Authorization Code Flow with PKCE

The SPA gets an ID token for identity and an access token for the API.

The API validates the access token.


Server-rendered web application

Use:

OpenID Connect for login
Server-side session for browser state
OAuth 2.0 access tokens if the server calls APIs

The backend can store tokens server-side.

The browser gets a secure session cookie.


Mobile application

Use:

OpenID Connect for login
OAuth 2.0 access tokens for APIs
Authorization Code Flow with PKCE
System browser for authentication

Avoid embedded web views for login.

Use the platform browser or secure authentication session APIs.


Machine-to-machine service

Use:

OAuth 2.0 client credentials
Access tokens
No OpenID Connect unless a user identity is involved

There is usually no ID token because there is no human user.


Third-party integration platform

Use:

OAuth 2.0 authorization flows
Granular scopes
Consent screens
Access token validation
Refresh token rotation where needed

OpenID Connect may be used for user login, but OAuth 2.0 is the core of delegated access.


How to explain this to your team

Use this simple rule:

OAuth 2.0 lets apps access APIs.
OpenID Connect lets apps know who logged in.

Then add:

Access tokens go to APIs.
ID tokens go to clients.

And finally:

Scopes describe permissions.
Claims describe identity and token metadata.

This mental model prevents many design mistakes.


Developer checklist

Use this checklist when designing authentication and authorization.

If users log in

  • Use OpenID Connect.
  • Request the openid scope.
  • Validate the ID token.
  • Use nonce where appropriate.
  • Treat the ID token as identity information for the client.
  • Do not use the ID token as the API credential.

If your app calls an API

  • Use OAuth 2.0 access tokens.
  • Validate access tokens at the API.
  • Check issuer, audience, signature, expiration, and scopes.
  • Use short-lived access tokens.
  • Do not rely on frontend-only authorization checks.

If your app needs both

  • Use OpenID Connect plus OAuth scopes.
  • Request identity scopes and API scopes.
  • Use the ID token for login state.
  • Use the access token for API calls.
  • Keep token audiences separate.

If there is no user

  • Use OAuth 2.0 client credentials.
  • Issue access tokens to machine clients.
  • Use scopes for service permissions.
  • Do not use OpenID Connect unless you need identity.

OpenID Connect vs OAuth 2.0 comparison table

Question OAuth 2.0 OpenID Connect
What problem does it solve? Authorization Authentication
Main token Access token ID token
Used by APIs and resource servers Client applications
Answers What can access what? Who is the user?
Standard user identity? No Yes
Standard login layer? No Yes
Built on OAuth 2.0? Base framework Yes
Uses scopes? Yes Yes
Useful for APIs? Yes Indirectly
Useful for login? Not by itself Yes

How BlitzWare helps

BlitzWare is designed to help developers implement authentication and authorization without rebuilding the same security-sensitive infrastructure from scratch.

With BlitzWare, you can build systems that need:

  • OAuth 2.0 authorization
  • User authentication
  • Social login
  • API authentication
  • User management
  • MFA
  • RBAC
  • Database connections
  • Customizable hosted authentication pages
  • Authentication analytics
  • License-key authentication
  • Device locking

For teams building SaaS products, APIs, dashboards, internal tools, and developer platforms, the goal is to keep the hard authentication logic centralized while giving developers the flexibility they need.

You can learn more on the OAuth Authentication product page, Direct API Authentication product page, and Database Connections product page.


Final thoughts

OAuth 2.0 and OpenID Connect are closely related, but they are not interchangeable.

OAuth 2.0 is about authorization.

OpenID Connect is about authentication.

Access tokens are for APIs.

ID tokens are for clients.

Scopes describe access.

Claims describe identity and token metadata.

If you remember only one thing, remember this:

Use OpenID Connect to log users in.
Use OAuth 2.0 access tokens to call APIs.

Once that distinction is clear, the rest of the architecture becomes much easier to reason about.

You will know which tokens to request, where to send them, how to validate them, and which security checks belong in the frontend versus the backend.

That clarity is what keeps authentication systems secure, maintainable, and understandable as your product grows.