OAuth 2.0 is a standard for letting one app act on your behalf at another service without ever seeing your password. You approve a request on the service's own sign-in page, and the app receives an access token limited to the scopes you agreed to. It handles authorization; OpenID Connect adds sign-in on top.
| OAuth 2.0 | OpenID Connect | SAML 2.0 | |
|---|---|---|---|
| Answers | What may this app access? | Who is this user? | Who is this user? |
| Main artefact | Access token | ID token (a JWT) plus access token | XML assertion |
| Spec | RFC 6749 (IETF) | OpenID Connect Core 1.0 | OASIS SAML 2.0 |
| Parties | Client, authorization server, resource server | Relying party, OpenID provider | Service provider, identity provider |
| Typical use | API access, "connect your account" | "Sign in with" buttons, mobile and SPA login | Workplace single sign-on |
Updated
Before OAuth, connecting two services often meant typing your password for one into the other. OAuth replaced that with short-lived, narrowly scoped tokens issued only after you approve. The generator below makes a real PKCE verifier and challenge in your browser and builds the authorization URL, so you can see each parameter the flow uses.
Creates a fresh code_verifier and its S256 code_challenge with your browser's crypto, then assembles an authorization URL from your settings. Nothing is sent; the endpoint below is a placeholder you replace.
| Step | From to | Key parameters |
|---|---|---|
| 1. Authorization request | App to authorization server (browser redirect) | response_type=code, client_id, redirect_uri, scope, state, code_challenge, code_challenge_method=S256 |
| 2. Sign in and consent | User at authorization server | Credentials never reach the app |
| 3. Redirect back | Authorization server to app | code, state |
| 4. Token request | App to token endpoint (direct POST) | grant_type=authorization_code, code, redirect_uri, client_id, code_verifier |
| 5. Token response | Token endpoint to app | access_token, token_type, expires_in, optional refresh_token (and id_token with OIDC) |
| 6. API call | App to resource server | Authorization: Bearer <access_token> |
32 random bytes encoded as base64url give a 43-character verifier, the shortest length RFC 7636 allows.
const b64url = (bytes) =>
btoa(String.fromCharCode(...bytes)).replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, "");
const verifier = b64url(crypto.getRandomValues(new Uint8Array(32)));
const digest = await crypto.subtle.digest("SHA-256", new TextEncoder().encode(verifier));
const challenge = b64url(new Uint8Array(digest));
sessionStorage.setItem("pkce_verifier", verifier);Runs after the redirect. Compare state first, then send the stored verifier with the code.
const params = new URLSearchParams(location.search);
if (params.get("state") !== sessionStorage.getItem("oauth_state")) throw new Error("state mismatch");
const res = await fetch("https://auth.example.com/oauth/token", {
method: "POST",
headers: { "Content-Type": "application/x-www-form-urlencoded" },
body: new URLSearchParams({
grant_type: "authorization_code",
code: params.get("code"),
redirect_uri: "https://app.example.com/callback",
client_id: "my-client-id",
code_verifier: sessionStorage.getItem("pkce_verifier"),
}),
});
const tokens = await res.json(); // { access_token, token_type, expires_in, ... }
RFC 6749 names four parties. The resource owner is you. The client is the app asking for access. The authorization server checks who you are and issues tokens. The resource server hosts the API that accepts those tokens. Often one company runs both servers, but they are separate jobs.
The redirect back to the app travels through the browser, which is a leaky place for anything valuable. So the redirect carries only a one-time code, which the spec recommends expire within 10 minutes. The real token is fetched in a direct call to the token endpoint.
PKCE closes the remaining gap. Even if malware or a logging proxy captures the code, it cannot redeem it without the verifier that never left the app.
OpenID Connect is a thin layer on OAuth. Add openid to the scopes, which the OIDC spec makes mandatory, and the token response also carries an ID token: a signed JWT describing the user. A nonce sent in the request and echoed in the ID token protects against replay.
Authorization. An access token says what an app may do, not who the user is, and APIs may not even tell you. When you need the person's identity, use OpenID Connect, which returns a signed ID token with claims such as sub, iss, aud and exp.
PKCE (RFC 7636) binds the authorization code to the app that started the flow. The app sends a hash of a random secret first and the secret itself later, so a stolen code is useless. Use S256, which servers must support, rather than plain.
SAML is an older XML-based standard where an identity provider sends a signed assertion about the user to a service provider, mostly for enterprise single sign-on in browsers. OAuth issues tokens for API access and works well for mobile apps and APIs. OpenID Connect is the closer OAuth-world equivalent of SAML sign-in.
Scopes are the permissions an app asks for, written as a space-separated list of case-sensitive strings that the authorization server defines, for example openid email or repo read:user. The consent screen shows them, and the token only covers what was approved.
No for new work. It returned tokens in the URL fragment where they can leak through history and logs. The authorization code flow with PKCE gives browser apps the same convenience without that exposure.
Related: What is a JWT, Website authentication guide, Next.js authentication, CORS explained, API key generator.
Start for free or see all free tools. We.Inc is free to start, with no card needed. AI building is on paid plans from $20 a month.
We.Inc is an AI-powered website builder you can resell under your own brand. Launch a branded client dashboard, bill on Stripe Connect, and deliver AI-generated websites in minutes. White-label plans start at $99 a month for 25 client sites, with a 7-day free trial and no per-site fees.