OAuth 2.0 · Authorization Code + PKCE

Experience Real OAuth

Learn how OAuth actually works by doing it — a guided, hands-on journey built for QA and automation engineers, not a documentation portal.

The complete OAuth journey

Sign in once, and watch the whole flow happen

Experience a complete OAuth 2.0 Authorization Code + PKCE flow: sign in with your Playwright Identity, approve consent, and securely land inside CineVerse using real OAuth — not a simulation.

Continue with Playwright Identity

No account yet? Create a Playwright Identity

Just exploring? Use the demo identity identity.demo@playwrightautomation.com / Password123.

Supporting lesson
Authentication vs Authorization

Want to see just the first step on its own? Sign in directly to the Authorization Server to learn how it proves who you are (authentication) and opens a server-side session — separate from what an application is allowed to access (authorization).

Sign in to the Authorization Server →

Replay the OAuth conversation

Your browser already completed this inside CineVerse. Now reproduce every step manually — the same requests, in the same order, against the real backend. Watch what each request does, what gets stored, and what changes.

Step 1 of 5
  1. The story. Your browser showed a sign-in screen for your Playwright Identity, then sent your credentials to the Authorization Server to start a session.

    🌐 BrowserPOST /api/oauth/as/loginAuth Server checks credentials

    Purpose. Create the Authorization Server session that identifies you for the rest of the flow.

    ✓ Session created.
Step 1 — Sign in to the Authorization Server
🌐 Browser200 · session establishedCookie pw_as_session stored

Why. The server set an HttpOnly pw_as_session cookie — it now trusts your browser for the consent step.

Behind the scenes
MethodPOST
URL/api/oauth/as/login
HeadersContent-Type: application/json
Body{ "email": "…", "password": "…" }
Response

In automation this is your login request. Capture the Set-Cookie: pw_as_session once, then reuse it via Playwright storageState (or a saved cookie) so later tests skip the UI login entirely.

🔍DevTools (Step 1). Open F12 → Application → Cookies → localhost → see pw_as_session (HttpOnly).
POST{{baseUrl}}/api/oauth/as/login
Headers
Content-Type: application/json
Body
{
  "email": "identity.demo@playwrightautomation.com",
  "password": "Password123"
}
Authorization
Set automatically — the response returns Set-Cookie: pw_as_session
Variables used in this request
VariableValueSource
baseUrlEnvironment
Actual runtime requestwhat the browser actually sent
Execute this step to see the real request (with variables resolved).
Example response
200 OK
{ "subject": "pwsub_…", "expiresAt": … }
Set-Cookie: pw_as_session=…; HttpOnly
Why / next / mistakes

Why this request exists. It authenticates the resource owner and starts the AS session that /authorize needs.

What happens next. The browser can now request authorization (Step 2).

Common mistakes. Forgetting cookies are per-host — run the whole flow on one origin (localhost).

Browser authentication vs API authentication

Browser (UI)

CookieSent automaticallyUI authentication

The browser attaches the session cookie to every request. In UI automation you reuse it as storageState.

API

Bearer tokenAuthorization headerAPI authentication

You attach the token per request. In API automation you obtain it once and inject it into every call.

Run the whole flow in Postman

Prefer an API client? Download a ready-to-run Postman collection and a matching localhost environment — the same requests you just replayed, pre-wired with PKCE generation and automatic token capture.

Quick start
  1. 1Import Collection
  2. 2Import Environment — then select it
  3. 3Run Login (request 1)
  4. 4Run Authorize → Consent → Token (access token saved automatically)
  5. 5Run UserInfo (request 5)
  6. Done — you called a protected API with a real token.

Automate OAuth like an enterprise QA team

You experienced it (Tab 1) and replayed every request (Tab 2). Now the real question: how do QA automation engineers automate this without logging in before every test?

How automation frameworks avoid logging in every test

Learn how Playwright, Selenium and Cypress authenticate once, save the session or token, and reuse it across hundreds of automated tests — instead of logging in through the UI before every single test.

Authenticate onceReuse sessionReuse storage stateReuse API tokenRun tests faster
Open CineVerse (already signed in)
Injected call
Run Tab 2 · Step 4 (Token) to enable this.

Be precise: a Bearer token authenticates API requests — it does not automatically become a browser cookie session. Real frameworks reuse the session (storageState) for the UI and the token for APIs.

1 Enterprise OAuth architecture

Where automation plugs in.

Browser Authorization Server Authorization Code Token Endpoint Access Token Protected APIs Browser Session Automation Framework ← automation starts here Test Suite
2 · Three enterprise patterns
Pattern 1 · UI (Storage State)
UI loginSave storageStateReuse storageRun UI tests

Where. End-to-end UI suites — the browser stays logged in via the saved session cookie.

Pattern 2 · API (Bearer token)
API loginAccess tokenAPI testingProtected APIs

Where. Fast API/contract tests — attach the token as Authorization: Bearer.

Pattern 3 · Hybrid
API loginInject authenticationAlready-authenticated browserContinue UI

Where. Big suites — skip the slow UI login, seed the session, then drive the UI.

3 Production examples

Clean, commented, framework-idiomatic — the authenticate-once pattern in each stack.


      

4 The real framework workflow
Authenticate onceGenerate tokenSave storage stateRun hundreds of testsReuse authenticationNever login again
5 Token injection — honestly
API loginReceive access tokenInject into request contextAuthenticated API calls

In Playwright you inject the token into an APIRequestContext (or set an extraHTTPHeaders Authorization header) — every API call is now authenticated.

Be completely honest. A Bearer token is not a browser login. Browsers authenticate the UI with a session cookie; APIs authenticate with a Bearer token. You cannot turn a Bearer token into a UI session just by putting it in storage. For the UI you reuse the session (storageState / the session cookie); for APIs you reuse the token. That is why "hybrid" seeds the session cookie for the browser, not the access token.
6 Playwright best practices
  • storageState() — save the authenticated cookies/origin storage to a file and reuse it.
  • request.newContext() / APIRequestContext — log in and call APIs without a browser.
  • globalSetup — authenticate once before the whole suite runs.
  • Project dependencies — a "setup" project that other projects depend on for auth.
  • Authentication fixtures — per-role fixtures that hand each test the right state.
  • Reuse login across specs instead of logging in per test.
  • Parallel execution — every worker reuses the same saved state, no login storms.
  • Multiple users / Admin & User — one storageState file per role; pick per test.
  • Role testing — swap storageState to assert role-specific behaviour.
7 Enterprise folder structure
framework/
├─ tests/       # specs / scenarios
├─ pages/       # Page Objects (UI locators & actions)
├─ fixtures/    # custom test fixtures (inject auth, data)
├─ api/         # API clients & token helpers
├─ auth/        # login flows + globalSetup (authenticate once)
├─ storage/     # saved storageState JSON (gitignored)
├─ config/      # env & runtime config
├─ helpers/     # shared utilities
└─ data/        # test data / fixtures

auth/ + storage/ are the heart of reuse: log in once in auth/, drop the result in storage/, and every test reads it.

8 Common mistakes
  • Logging in through the UI in every test — authenticate once, reuse storageState.
  • Generating a fresh token on every request — cache it until it expires.
  • Sharing an expired storageState — refresh it in globalSetup or on expiry.
  • Mixing cookies and Bearer tokens — cookies auth the UI, Bearer auths APIs; don’t cross them.
  • Ignoring refresh tokens — renew the access token instead of re-logging in.
  • Using UI login when an API login works — API login is faster and more stable.
9 When to use which strategy
You need…Use
UI testsStorage State (session cookie)
API testsBearer access token
Both (hybrid)API login → inject session for UI + token for APIs
Multiple usersOne storageState file per user
Admin + userSeparate authentication contexts / projects
Long suitesAuthenticate once in globalSetup
🎉 Now you know how enterprises automate OAuth.

Next, implement these patterns yourself — log in once, save the state, and reuse it across a real suite.