sellIntegration
key

Auth flows, diagrammed

SSO, session cookies, JWT bearer tokens, and OAuth — each one drawn as a picture you can follow.

4Flows diagrammed
5Mermaid diagrams
0 codeFor Access SSO
insights

What are we diagramming?

Authentication can feel abstract because the important parts happen invisibly between the browser, your server, and an identity provider. This guide draws four of the most common login flows as sequence diagrams, so you can literally see who talks to whom, in what order, and what gets passed along.

lightbulb

Authentication vs authorization

Authentication answers 'who are you?' (showing your ID at the door). Authorization answers 'what are you allowed to do?' (whether your ticket lets you into the VIP room). Every flow below does authentication first, then carries proof of it on each later request.

schemaWhich auth flow should I use?

Yes

No

Server sessions

API or mobile app

Sign in with Google

Who is logging in?

Internal team app?

Cloudflare Access SSO

Web app with a login page?

Session cookie

JWT bearer token

OAuth third-party

badge

1. Cloudflare Access SSO

SSO (Single Sign-On) means you log in once with one identity provider and then reach many apps without logging in again. With Cloudflare Access, Cloudflare sits in front of your app and handles the whole login — you write no auth code. After login, Cloudflare gives the browser a signed cookie that your app can trust.

schemaAccess SSO login
"Your app""Identity provider""Cloudflare Access""Browser""Your app""Identity provider""Cloudflare Access""Browser"Open the app URLNo session, redirect to loginSign in with GoogleIdentity confirmedSet signed Access cookieRequest with Access cookieVerify the cookieToken is validShow the protected page
verified_user

Why teams love it

Your app never sees passwords and you write zero login logic. Cloudflare enforces the policy (who is allowed) and only forwards verified requests. Perfect for internal dashboards and admin panels.

cookie

2. Session-cookie login

A session is the server's memory of one logged-in visitor. After you log in, the server stores a session record (here in Workers KV) and hands the browser a cookie holding only a random session id. The browser sends that cookie on every later request, and the server looks the id up to know who you are. This is the classic flow for server-rendered web apps.

schemaSession cookie lifecycle
"Workers KV""Worker""Browser""Workers KV""Worker""Browser"Next request, cookie attachedPOST email and passwordVerify the passwordStore a new sessionSavedReply with session cookieGET dashboard with cookieLook up the session idSession valid, user idRender the dashboard
lock

Keep the cookie safe

Set the cookie as HttpOnly (JavaScript cannot read it), Secure (HTTPS only), and SameSite to reduce CSRF. Give the KV session a TTL so it expires automatically. The cookie itself holds no user data — just the lookup key.

token

3. JWT bearer-token API auth

A JWT (JSON Web Token) is a signed string that carries claims like the user id and an expiry time. Because it is signed with a secret, the server can trust it without storing anything — it just checks the signature. The client sends it in an Authorization header as a 'bearer' token, meaning 'whoever bears this token is allowed in'. This is the go-to flow for APIs, single-page apps, and mobile apps.

schemaJWT bearer-token flow
"Worker API""Client""Worker API""Client"Store token in memoryPOST login with credentialsSign a JWT with the secretReturn the JWTGET data with bearer headerVerify the JWT signatureReturn JSON data
jsworker-verify-bearer.js
export default {
  async fetch(req, env) {
    const header = req.headers.get("Authorization") || "";
    const [scheme, token] = header.split(" ");
    if (scheme !== "Bearer" || !token) {
      return new Response("Missing bearer token", { status: 401 });
    }
    const valid = await verifyJWT(token, env.JWT_SECRET);
    if (!valid) return new Response("Invalid token", { status: 401 });
    return Response.json({ ok: true, message: "Welcome back!" });
  }
};

// Verify an HS256 JWT signature with the Web Crypto API
async function verifyJWT(token, secret) {
  const [head, body, sig] = token.split(".");
  if (!head || !body || !sig) return false;
  const key = await crypto.subtle.importKey(
    "raw",
    new TextEncoder().encode(secret),
    { name: "HMAC", hash: "SHA-256" },
    false,
    ["verify"]
  );
  const signed = new TextEncoder().encode(head + "." + body);
  const bytes = Uint8Array.from(
    atob(sig.replace(/-/g, "+").replace(/_/g, "/")),
    (c) => c.charCodeAt(0)
  );
  return crypto.subtle.verify("HMAC", key, bytes, signed);
}
schedule

Verifying the signature is not enough

After the signature checks out, also decode the payload and reject the token if its exp (expiry) has passed. Keep tokens short-lived (minutes to an hour) and store the secret in a Worker secret, never in code.

link

4. OAuth third-party login

OAuth lets users log in with an account they already have, like Google or GitHub, without giving your app their password. Your app redirects the user to the provider, the user approves, and the provider redirects back with a short-lived code. Your app then swaps that code for an access token on the server side. The 'authorization code' style below is the secure, recommended pattern.

schemaOAuth authorization code flow
"OAuth provider""Your app""Browser""OAuth provider""Your app""Browser"Click sign in with GoogleRedirect to the providerReview and approve consentRedirect back with a codeDeliver the codeExchange code for a tokenAccess token and profileLogged in, set a session
shield

Code, not token, in the browser

The browser only ever sees a one-time code; the real token is fetched server-to-server so it never leaks. Keep the client secret on the server, and use a state value plus PKCE to block forged callbacks.

target

When to use each

badge

Access SSO

Internal tools for your own team. No login code to write — Cloudflare guards the door and enforces who gets in.

cookie

Session cookie

Traditional, server-rendered websites where the browser is the only client. Simple to reason about and easy to revoke.

token

JWT bearer

APIs, single-page apps, mobile apps, and service-to-service calls. Stateless — no session store needed.

link

OAuth

Let users sign in with Google, GitHub, or similar — or access their data on those services with their permission.

school

Key terms

key

SSO

Single Sign-On: log in once, reach many apps without logging in again.

history

Session

The server's record of one logged-in visitor, usually kept in a store like KV.

cookie

Cookie

A small value the browser stores and resends on every request — here it carries the session id.

token

JWT

A signed JSON token holding claims (user id, expiry) that the server can trust without a lookup.

vpn_key

Bearer token

Sent as 'Authorization: Bearer <token>'. Whoever holds it is treated as authorized.

link

OAuth

A standard for logging in with another service's account without sharing your password.

tips_and_updates

Tips & gotchas

https

Always over HTTPS

Cookies and bearer tokens are like keys — anyone who copies them can impersonate the user. HTTPS keeps them from being read in transit, and is on by default for any Cloudflare-proxied domain.

  • Never store a raw JWT or session id in localStorage if you can avoid it — an HttpOnly cookie is safer against XSS.
  • Always verify a JWT's signature AND its expiry on the server; never trust the payload alone.
  • For pure internal tools, Cloudflare Access often replaces all of this with zero auth code.
  • Add Turnstile to your login form to block bots before they ever reach your password check.
  • Give sessions and tokens a short lifetime, and provide a real logout that deletes the server-side session.