Intermediate
Chapter 8 · 12 min read
Authentication & Authorization
Implement Bearer tokens, Basic auth, API keys, and OAuth2 flows. Test protected endpoints and validate access control.
API Authentication & Authorization
Most real-world APIs require authentication. Understanding different auth mechanisms and testing them properly is crucial for any API tester.
Common Authentication Methods
- Bearer Token — A token (often JWT) sent in the Authorization header. Most common in modern APIs.
- Basic Auth — Username and password encoded in Base64. Simple but less secure.
- API Key — A static key sent as a header or query parameter. Common in third-party APIs.
- OAuth 2.0 — A delegation framework for granting limited access. Used by Google, GitHub, etc.
What to Test
Test both happy paths (valid credentials) and negative scenarios: expired tokens, invalid tokens, missing auth, wrong permissions, and token refresh flows.
auth.test.js
// Bearer Token Authentication
const token = 'your-jwt-token-here';
const bearerResponse = await fetch('https://httpbin.org/bearer', {
headers: {
'Authorization': `Bearer ${token}`
}
});
console.log('Bearer status:', bearerResponse.status);
// Basic Authentication
const username = 'testuser';
const password = 'testpass';
const basicCredentials = btoa(`${username}:${password}`);
const basicResponse = await fetch(
`https://httpbin.org/basic-auth/${username}/${password}`, {
headers: {
'Authorization': `Basic ${basicCredentials}`
}
});
const basicData = await basicResponse.json();
console.assert(basicResponse.status === 200);
console.assert(basicData.authenticated === true);
// API Key in header
const apiKeyResponse = await fetch('https://httpbin.org/headers', {
headers: {
'X-API-Key': 'my-secret-api-key'
}
});
const apiData = await apiKeyResponse.json();
console.log('API Key sent:', apiData.headers['X-Api-Key']);
// API Key as query parameter
const apiKeyQueryResp = await fetch(
'https://httpbin.org/get?api_key=my-secret-api-key'
);
// Test missing auth — should return 401
const noAuthResponse = await fetch('https://httpbin.org/bearer');
console.assert(noAuthResponse.status === 401, 'Should be 401 without token');
// Reusable auth helper
function createAuthHeaders(token) {
return {
'Authorization': `Bearer ${token}`,
'Content-Type': 'application/json'
};
}
console.log('All auth tests passed!');
AuthenticationTest.java
import static io.restassured.RestAssured.*;
import static org.hamcrest.Matchers.*;
import io.restassured.specification.RequestSpecification;
import org.testng.annotations.Test;
public class AuthenticationTest {
@Test
public void testBearerToken() {
String token = "your-jwt-token-here";
given()
.header("Authorization", "Bearer " + token)
.when()
.get("https://httpbin.org/bearer")
.then()
.statusCode(200)
.body("authenticated", equalTo(true));
}
@Test
public void testBasicAuth() {
given()
.auth().preemptive().basic("testuser", "testpass")
.when()
.get("https://httpbin.org/basic-auth/testuser/testpass")
.then()
.statusCode(200)
.body("authenticated", equalTo(true))
.body("user", equalTo("testuser"));
}
@Test
public void testApiKeyInHeader() {
given()
.header("X-API-Key", "my-secret-api-key")
.when()
.get("https://httpbin.org/headers")
.then()
.statusCode(200)
.body("headers.X-Api-Key", equalTo("my-secret-api-key"));
}
@Test
public void testMissingAuth_ShouldReturn401() {
given()
.when()
.get("https://httpbin.org/bearer")
.then()
.statusCode(401);
}
// Reusable auth spec
private RequestSpecification authSpec(String token) {
return given()
.header("Authorization", "Bearer " + token)
.contentType("application/json");
}
}
test_authentication.py
import requests
from requests.auth import HTTPBasicAuth
import base64
def test_bearer_token():
"""Bearer token authentication"""
token = 'your-jwt-token-here'
response = requests.get(
'https://httpbin.org/bearer',
headers={'Authorization': f'Bearer {token}'}
)
assert response.status_code == 200
assert response.json()['authenticated'] is True
def test_basic_auth():
"""Basic authentication — Requests makes this easy"""
response = requests.get(
'https://httpbin.org/basic-auth/testuser/testpass',
auth=HTTPBasicAuth('testuser', 'testpass')
)
assert response.status_code == 200
assert response.json()['authenticated'] is True
assert response.json()['user'] == 'testuser'
def test_api_key_header():
"""API key in custom header"""
response = requests.get(
'https://httpbin.org/headers',
headers={'X-API-Key': 'my-secret-api-key'}
)
assert response.status_code == 200
assert response.json()['headers']['X-Api-Key'] == 'my-secret-api-key'
def test_api_key_query_param():
"""API key as query parameter"""
response = requests.get(
'https://httpbin.org/get',
params={'api_key': 'my-secret-api-key'}
)
assert response.status_code == 200
def test_missing_auth():
"""Missing auth should return 401"""
response = requests.get('https://httpbin.org/bearer')
assert response.status_code == 401
# Reusable session with auth
def create_auth_session(token):
session = requests.Session()
session.headers.update({
'Authorization': f'Bearer {token}',
'Content-Type': 'application/json'
})
return session
API Testing
Intermediate
Authentication & Authorization
Written by PV
© 2026 All Rights Reserved