Most real-world APIs require authentication. As a tester, you need to verify that authentication works correctly — and that unauthenticated requests are properly rejected.
Authentication Types
API Key
The simplest form. Include a key in the header or query parameter:
Header: X-API-Key: abc123def456
— or —
URL: https://api.example.com/data?api_key=abc123def456
In Postman:
- Go to the Auth tab
- Select API Key
- Set Key:
X-API-Key, Value:{{api_key}} - Choose "Header" as the location
Basic Authentication
Sends a Base64-encoded username and password:
Header: Authorization: Basic c2FiYW9vbjpwYXNzd29yZA==In Postman:
- Go to the Auth tab
- Select Basic Auth
- Enter username and password
- Postman encodes them automatically
Bearer Token / JWT
The most common pattern for modern APIs. You log in, get a token, and include it in subsequent requests:
Header: Authorization: Bearer eyJhbGciOiJIUzI1NiIs...In Postman:
- Go to the Auth tab
- Select Bearer Token
- Enter
{{access_token}}
OAuth 2.0
A more complex flow used by services like Google, GitHub, and Twitter. Postman has built-in OAuth 2.0 support:
- Go to the Auth tab
- Select OAuth 2.0
- Click Get New Access Token
- Fill in:
- Grant Type: Authorization Code
- Auth URL:
https://provider.com/authorize - Token URL:
https://provider.com/token - Client ID and Client Secret
- Postman handles the redirect flow and captures the token
Automating Token Retrieval
Don't manually copy tokens. Automate it with a login request:
Login request (Tests tab):
pm.test("Login successful", function () {
pm.response.to.have.status(200);
const json = pm.response.json();
pm.environment.set("access_token", json.token);
pm.environment.set("refresh_token", json.refreshToken);
});Now every request that uses {{access_token}} automatically gets the fresh token.
What to Test
Positive Auth Tests
| Test | Expected |
|---|---|
| Login with valid credentials | 200 + token returned |
| Access protected route with valid token | 200 + data returned |
| Refresh expired token | 200 + new token |
Negative Auth Tests
| Test | Expected |
|---|---|
| Login with wrong password | 401 Unauthorized |
| Access protected route without token | 401 Unauthorized |
| Access protected route with expired token | 401 Unauthorized |
| Access protected route with malformed token | 401 Unauthorized |
| Access admin route as regular user | 403 Forbidden |
| Login with SQL injection in email field | 400 Bad Request (not 500) |
Edge Cases
| Test | Expected |
|---|---|
| Login with empty email | 400 with validation error |
| Login with empty password | 400 with validation error |
| Multiple rapid login attempts | 429 Rate Limited (after threshold) |
| Use token after logout | 401 Unauthorized |
| Use token from a different user | 403 Forbidden |
Testing JWT Tokens
JWTs have three parts: header, payload, and signature. You can decode them in Postman:
pm.test("Token has correct claims", function () {
const token = pm.environment.get("access_token");
const payload = JSON.parse(atob(token.split('.')[1]));
pm.expect(payload).to.have.property("sub");
pm.expect(payload).to.have.property("exp");
pm.expect(payload.exp).to.be.above(Date.now() / 1000);
});Collection-Level Auth
Instead of adding auth to every request individually, set it at the collection level:
- Click your collection name
- Go to the Auth tab
- Set Bearer Token with
{{access_token}} - All requests in the collection inherit this auth
- Individual requests can override it if needed
Token Refresh Flow
A common pattern to test:
1. Login → Get access_token (15 min) + refresh_token (7 days)
2. Make requests with access_token
3. access_token expires → Get 401
4. Send refresh_token to /refresh → Get new access_token
5. Resume making requestsTest that:
- Expired access tokens are rejected
- Refresh tokens generate new access tokens
- Expired refresh tokens are rejected
- Used refresh tokens are invalidated (rotation)