Testing JWT Authentication in Postman, Playwright & Rest Assured (2026)
End-to-end guide to testing JWT auth flows: obtain, decode, tamper, expire, and reuse tokens across Postman collections, Playwright fixtures, and Rest Assured suites.

2026-07-17 · By Avinash K
Almost every API you test in 2026 uses JWT bearer tokens. This guide gives you copy-paste-ready scripts for the three tools QA teams actually run: Postman for exploratory + collection runs, Playwright for full E2E with UI, and Rest Assured for Java-based backend suites.
Step 1 — obtain a token once, reuse everywhere
Do not log in inside every test. Grab a token in a setup step and inject it via header. Refresh only when it's within 60s of exp.
Postman — pre-request script
// collection-level pre-request
const token = pm.environment.get("access_token");
const exp = pm.environment.get("access_token_exp");
if (!token || Date.now()/1000 > exp - 60) {
pm.sendRequest({
url: pm.environment.get("auth_url") + "/token",
method: "POST",
header: { "Content-Type": "application/x-www-form-urlencoded" },
body: { mode: "urlencoded", urlencoded: [
{ key: "grant_type", value: "password" },
{ key: "username", value: pm.environment.get("test_user") },
{ key: "password", value: pm.environment.get("test_pass") },
]},
}, (err, res) => {
const jwt = res.json().access_token;
const payload = JSON.parse(atob(jwt.split(".")[1]));
pm.environment.set("access_token", jwt);
pm.environment.set("access_token_exp", payload.exp);
});
}Playwright — auth fixture with token cache
// tests/fixtures/auth.ts
import { test as base, request } from "@playwright/test";
export const test = base.extend<{ token: string }>({
token: async ({}, use) => {
const ctx = await request.newContext();
const res = await ctx.post(process.env.AUTH_URL + "/token", {
form: { grant_type: "password", username: "qa", password: process.env.QA_PASS },
});
const { access_token } = await res.json();
await use(access_token);
},
});
// tests/orders.spec.ts
test("create order", async ({ token, request }) => {
const res = await request.post("/api/orders", {
headers: { Authorization: `Bearer ${token}` },
data: { sku: "A1", qty: 2 },
});
expect(res.status()).toBe(201);
});Rest Assured — @BeforeAll token fetch
@BeforeAll
static void auth() {
token = given()
.contentType("application/x-www-form-urlencoded")
.formParam("grant_type", "password")
.formParam("username", System.getenv("QA_USER"))
.formParam("password", System.getenv("QA_PASS"))
.post(System.getenv("AUTH_URL") + "/token")
.jsonPath().getString("access_token");
}
@Test
void createOrder() {
given().header("Authorization", "Bearer " + token)
.contentType(ContentType.JSON)
.body(Map.of("sku", "A1", "qty", 2))
.when().post("/api/orders")
.then().statusCode(201);
}Negative tests you must run
- Send request with no Authorization header → 401.
- Send with tampered signature (change one char) → 401.
- Send with
alg:noneforged token → 401. - Send with expired token (
exp= yesterday) → 401. - Send with token from another tenant → 403.
Generate forged tokens in one click
Instead of hand-crafting attack payloads, open the JWT Debugger, load a sample attack (alg=none, weak-secret, expired, kid-injection), copy the token, and paste it into your Postman/Playwright/Rest Assured negative-test suite.