Skip to content
apikey.tools
SIMTesting

Mock Authorization Header Builder

Build Bearer, Basic, ApiKey and Token headers for tests and fixtures.

SIMRuns in this tabInput not transmitted

Input

Output

computing

Tests need credential-shaped values. Using a real key in a test fixture is how real keys reach public repositories, so this builds headers that look right and authenticate to nothing.

Test the rejection paths

Most authentication test suites cover one case: a valid credential succeeds. The cases that actually break in production are the others, and each needs a distinct header to exercise:

CaseHeaderExpected
No credential*(omit)*401 with WWW-Authenticate
Wrong schemeBasic <token>401
MalformedBearer with no value401
Unknown credentialBearer invalid401
Expired tokena token past exp401
Valid but under-scopedvalid token, wrong scope403, not 401

That last row is the one most often wrong. A scope failure is 403 — the caller is authenticated, they are simply not permitted. Returning 401 sends well-behaved clients into a refresh loop that can never succeed.

Distinguish 401 from 403 in tests

javascript
test("refreshes once on 401, then gives up", async () => {
  fetchMock
    .mockResolvedValueOnce(new Response(null, { status: 401 }))
    .mockResolvedValueOnce(new Response("{}", { status: 200 }));

  await client.get("/resource");
  expect(refreshToken).toHaveBeenCalledTimes(1);
});

test("does not retry a 403", async () => {
  fetchMock.mockResolvedValue(new Response(null, { status: 403 }));

  await expect(client.get("/resource")).rejects.toThrow();
  expect(refreshToken).not.toHaveBeenCalled();
});

Never use a real key in a fixture

Even an expired one, even a test-environment one. Test fixtures get committed, and a scanner cannot tell that your sk_test_ key is harmless. Worse, the habit means that one day a sk_live_ key gets pasted into the same place.

Generate values here, or use the provider format generator when the shape needs to match a specific vendor.

Basic auth in tests

Basic encodes username:password as Base64. When an API uses the key-as-username convention, the trailing colon matters: sk_test_abc: and sk_test_abc produce different Base64, and forgetting it produces a test that fails for a reason unrelated to what it is testing.

Frequently asked questions

Should tests use a real token from the auth server?

Integration tests, yes — that path is worth exercising. Unit tests, no: they should not depend on a network service. Mint a token locally with the OAuth token generator and stub the verification.

How do I test token expiry without waiting?

Generate a token with an exp in the past, or inject a clock into your validator so tests can advance time. The expiry calculator produces the timestamps.

What should a 401 response include?

A WWW-Authenticate header naming the scheme, and a body that does not reveal whether the credential exists. "Invalid credentials" for both unknown and wrong keys denies an attacker a key-enumeration oracle.

Is it safe to commit these generated headers?

Yes. They are random values that authenticate to nothing. That is the point — they are safe where a real key is not.

More testing tools

Rehearse authentication before you ship it