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:
- Open the HeaderSnap popup from the Chrome toolbar
- Click Add Rule
- Set the URL pattern to match your API:
https://api.example.com/* - Add a request header:
- Name:
Authorization - Value:
Bearer <your-test-token>
- Name:
- 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-keyX-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:
-
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 correctscope,client_id, andredirect_uriare being sent. -
Authorization grant — After user login and consent, the auth server redirects back to your
redirect_uriwith acodeparameter:https://app.example.com/callback?code=abc123. Find this request in the Network tab. -
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, andredirect_uri. Find it in the Network tab and verify the response containsaccess_token,token_type, and optionallyrefresh_tokenandexpires_in. -
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_urimismatch — 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 stateparameter not being verified (a security gap, not just a debugging issue)- Token expiry — decode the
expclaim 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
- Open Chrome DevTools → Network → enable Preserve log
- Trigger the auth flow and trace it step-by-step in the Network tab
- Decode the JWT payload in the Console to inspect claims
- Use HeaderSnap to inject or override auth headers for specific test scenarios
- 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.