RestingOwl owl logo RestingOwl

OAuth 2.0 and OpenID Connect:Security Made Simple

Quick answer: OAuth 2.0 lets one app get permission to use another app's data on a user's behalf, without seeing the password. OpenID Connect adds a login layer on top, so the app also learns who the user is. To use them safely, pick the authorization code flow with PKCE, check the redirect address exactly, validate the state value and every token, and ask only for the permissions you need.

Almost every "Sign in with Google" or "Connect your account" button uses OAuth 2.0 and OpenID Connect. They are powerful, but small mistakes in how the pieces fit together can hand an attacker a full account. This guide explains the ideas in simple terms and shows the settings that keep them safe. It maps to chapter V10 of the OWASP standard, which you can browse in the ASVS Explorer.

What Is the Difference Between OAuth and OpenID Connect?

People mix these two up all the time, so it helps to separate them clearly. OAuth is about access. OpenID Connect is about identity.

OAuth 2.0OpenID Connect (OIDC)
Main jobGive an app permission to use dataTell an app who the user is
Answers the questionWhat is this app allowed to do?Who just logged in?
Main tokenAccess tokenID token (plus access token)
Everyday exampleLet an app read your calendarSign in with your Google account

OpenID Connect is built on top of OAuth, so a login usually gives you both an ID token (who the user is) and an access token (what the app can do). The ID token is a signed JWT. If you use tokens directly, our guide on JWT vs session tokens explains how to handle them.

How Does the Safe OAuth Flow Work?

The recommended flow is called the authorization code flow with PKCE (said "pixy"). In plain steps it works like this:

  1. Your app sends the user to the login provider with a request that includes a random value called state and a one time secret called a PKCE code.
  2. The user logs in at the provider, which your app never sees.
  3. The provider sends the user back to your exact redirect address with a short lived code.
  4. Your app checks that the returned state matches what it sent, then swaps the code plus the PKCE secret for tokens on a back channel that the browser cannot see.
  5. Your app validates the tokens and creates a session for the user.

PKCE matters because it ties the code to the app that started the flow. Even if an attacker steals the code, they cannot exchange it without the matching secret. This is why the older implicit flow, which returned tokens straight to the browser, is no longer recommended.

What Are the Most Common OAuth Mistakes?

  • Loose redirect addresses. If you allow wildcards or do not match the redirect URL exactly, an attacker can send the code to their own site. Always register and compare the full redirect address.
  • Skipping the state check. The state value stops cross site request forgery on the login flow. If you do not check it, an attacker can trick a user into linking the attacker's account.
  • Using the implicit flow. Returning tokens directly in the browser URL leaks them into history and logs. Use the authorization code flow with PKCE instead.
  • Trusting tokens without checking. Always validate the token signature, the issuer, the audience, and the expiry before you trust anything inside it.
  • Asking for too much. Requesting broad permissions (scopes) you do not need increases the damage if the token leaks. Ask for the minimum, and let users see what they are approving.

How Do You Validate OAuth and OIDC Tokens?

A token is only useful if you trust it, and you only trust it after checking it. For an ID token from OpenID Connect, confirm four things on every login: the signature is valid and made by the provider, the iss (issuer) is the provider you expect, the aud (audience) is your app, and the token has not expired. For access tokens, follow the provider's guidance, which is often to send the token to the provider's introspection endpoint or to verify it as a signed JWT. Never store secrets or long lived tokens in the browser where a script could read them.

OAuth and OIDC Security Checklist

OAuth and OpenID Connect Checklist
  1. 1Use the authorization code flow with PKCE for web and mobile apps.
  2. 2Register exact redirect addresses and compare them fully, with no wildcards.
  3. 3Generate and check the state value on every login to stop request forgery.
  4. 4Validate every token: signature, issuer, audience, and expiry.
  5. 5Request the smallest set of scopes your app needs.
  6. 6Keep client secrets on the server, never in browser or mobile app code.
  7. 7Give users a way to review and remove connected apps.
  8. 8Log login events and failures so you can spot abuse.
Go deeper: OAuth and OIDC are chapter V10 of the OWASP ASVS. See how they connect to authentication and tokens in the ASVS Explorer, and read JWT vs session tokens to handle the tokens you receive.

References

  1. 1OAuth 2.0 Security Best Current Practice (RFC 9700)
  2. 2OWASP ASVS 5.0: V10 OAuth and OIDC
  3. 3OpenID Connect Core Specification

Q&A Section

OAuth 2.0 is an authorization protocol. It grants access to data, but on its own it does not prove who the user is. OpenID Connect adds authentication on top of OAuth, so if you want to log a user in, you use OpenID Connect, which returns an ID token that identifies the user.
PKCE ties the authorization code to the app that started the flow using a one time secret, so a stolen code cannot be exchanged by anyone else. The current best practice is to use PKCE for all clients, including server side apps with a client secret, because it adds protection against code interception at no real cost.
The implicit flow returned tokens directly in the browser URL, where they can leak into browser history, server logs, and referrer headers. The authorization code flow with PKCE keeps tokens off the URL and exchanges the code on a back channel, which is much safer. Modern guidance from the IETF recommends the code flow with PKCE.
The state parameter is a random value your app sends at the start of the login and checks when the user returns. It ties the response to the request that started it, which blocks cross site request forgery attacks that try to link an attacker controlled account to a victim's session.
Copied!