How to Test JWT and OAuth2 Flows in Chrome — No Test Client Required — HeaderSnap ModHeader was removed from Chrome & Edge over a hidden data collector — what happened and what to do
HeaderSnap
March 17, 2026

How to Test JWT and OAuth2 Flows in Chrome (Without a Test Client)

Auth debugging has a setup tax. Most developers reach for Postman or Insomnia when they need to test JWT or OAuth2 flows — but that means context-switching out of the browser, recreating requests, and managing a separate tool that doesn’t always reflect what your browser is actually doing.

There’s a faster workflow: test auth flows directly in Chrome, using your real application as the test client, with a header editor to inject and modify auth tokens on demand.

This guide covers the full workflow: inspecting JWT structure, debugging OAuth2 authorization code flows, and testing Authorization, X-API-Key, and Cookie headers with HeaderSnap.


Understanding What You’re Actually Testing

Before getting into the tools, it helps to be clear about what “auth debugging” means in practice:

JWT debugging usually means:

  • Verifying the token structure (header, payload, signature)
  • Confirming the payload contains the right claims
  • Testing API endpoints with specific tokens — expired, modified, or from different users/roles
  • Debugging 401 and 403 errors by understanding what the server is rejecting

OAuth2 debugging usually means:

  • Following the authorization code flow step-by-step
  • Verifying the correct scopes are being requested
  • Testing what happens with different access tokens or after token expiry
  • Inspecting what’s in the authorization header vs. cookies vs. request body

Both problems benefit from the same approach: inspect what’s happening in the Network tab, then use a header editor to modify tokens and replay requests.


Step 1 — Inspect Token Structure in Chrome DevTools

Open Chrome DevTools (F12 → Network tab) and trigger an authenticated request in your application.

In the request headers, find your Authorization header. It typically looks like:

Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c

The JWT is three base64url-encoded segments separated by dots: header, payload, signature. To inspect the contents, paste the token into jwt.io (in a browser tab) or decode it inline:

// In the DevTools Console
const token = "eyJhbGciOiJI...";
const [header, payload] = token.split('.').slice(0,2);
console.log(JSON.parse(atob(payload.replace(/-/g, '+').replace(/_/g, '/'))));

This shows you the claims: sub (user ID), exp (expiry timestamp), roles, and any custom claims your application uses. Comparing what’s in the token against what the API expects usually points directly at the problem.


Step 2 — Inject and Test Authorization Headers with HeaderSnap

Once you know what token you want to test with — a different user’s token, an expired token, a token with different scopes — you need a way to inject it into your requests without modifying your application code.

HeaderSnap lets you inject or override the Authorization request header, scoped to specific URLs, from within the browser.

To inject a Bearer token:

  1. Open the HeaderSnap popup from the Chrome toolbar
  2. Click Add Rule
  3. Set the URL pattern to match your API: https://api.example.com/*
  4. Add a request header:
    • Name: Authorization
    • Value: Bearer <your-test-token>
  5. Click Add to save the rule

Now every request matching that URL pattern will use your test token — regardless of what your application sends. You can toggle the rule on and off to compare authenticated vs. unauthenticated behavior, or switch between rule sets for different test users.

Testing X-API-Key auth:

For services that use API key headers instead of Bearer tokens, use the same workflow with the appropriate header name:

  • X-API-Key: your-test-api-key
  • X-Auth-Token: your-token
  • Or whatever the service expects

Testing cookie-based auth:

For session cookie auth, add the Cookie request header:

  • Name: Cookie
  • Value: session_id=abc123; user_id=456

This overrides what your browser sends for matching URLs.


Step 3 — Debug the OAuth2 Authorization Code Flow

OAuth2 authorization code flows involve a series of redirects that can be hard to follow. Here’s how to trace the full flow in Chrome:

Enable Preserve Log in DevTools:

In the Network tab, check Preserve log. This prevents the Network tab from clearing when the page redirects — essential for following the OAuth2 dance.

Trace the flow:

  1. Authorization request — Your app redirects to https://auth.example.com/oauth/authorize?response_type=code&client_id=...&redirect_uri=...&scope=.... In the Network tab, find this request and check the query parameters. Confirm the correct scope, client_id, and redirect_uri are being sent.

  2. Authorization grant — After user login and consent, the auth server redirects back to your redirect_uri with a code parameter: https://app.example.com/callback?code=abc123. Find this request in the Network tab.

  3. Token exchange — Your backend (or a frontend SPA) exchanges the code for an access token via a POST to the token endpoint. This request should include the code, client_id, client_secret, and redirect_uri. Find it in the Network tab and verify the response contains access_token, token_type, and optionally refresh_token and expires_in.

  4. Authenticated API calls — Subsequent requests should include Authorization: Bearer <access_token>. Use HeaderSnap to override this with test tokens and observe how your API responds.

Common issues to look for:

  • redirect_uri mismatch — the URI in the token exchange must exactly match the one in the authorization request
  • Wrong or missing scope — check that the scopes in the authorization request match what your API requires
  • state parameter not being verified (a security gap, not just a debugging issue)
  • Token expiry — decode the exp claim from your JWT to confirm it’s not already expired

HeaderSnap’s URL Pattern Tester

One practical detail: when you set a URL pattern in HeaderSnap, it applies to all matching requests — including requests you might not intend. Before activating a rule, use HeaderSnap’s URL pattern tester to verify your pattern matches exactly the endpoints you want.

Enter a test URL to see which of your active rules would apply to it. This is especially useful when testing with regex patterns or when your API has multiple versions (/v1/, /v2/) that you want to handle differently.


Keeping Test Configurations Organized

If you regularly test multiple auth flows — different users, different token types, different environments — HeaderSnap’s profile system lets you keep these configurations separate.

Create a profile per scenario:

  • “Expired token test” — Authorization header with a manually expired JWT
  • “Admin user” — Token from an admin account for permission testing
  • “Staging” — Staging environment tokens

Switch between profiles from the HeaderSnap popup without losing any configuration.


The Full Workflow

  1. Open Chrome DevTools → Network → enable Preserve log
  2. Trigger the auth flow and trace it step-by-step in the Network tab
  3. Decode the JWT payload in the Console to inspect claims
  4. Use HeaderSnap to inject or override auth headers for specific test scenarios
  5. Compare behavior: toggle HeaderSnap rules on/off, switch profiles, test edge cases

This loop — inspect in DevTools, modify with HeaderSnap, reload, inspect again — replaces most of what you’d use a standalone test client for, without leaving the browser or recreating your request context from scratch.


👉 Install HeaderSnap free → No account required.