HTTP REQUESTS
Headers and Authentication
Overview
Effective API testing requires proper header management and authentication implementation. Karate provides flexible methods for setting headers, managing authentication tokens, and handling various security schemes.
HTTP Headers
Basic Header Management
# Individual headers
* header Accept = 'application/json'
* header Content-Type = 'application/xml'
* header X-API-Version = '2.0'
# Dynamic headers with expressions
* header Authorization = 'Bearer ' + authToken
* header X-Request-ID = java.util.UUID.randomUUID()
* header X-Timestamp = new Date().getTime()
# Headers from functions
* def getTraceId = function(){ return 'trace-' + java.util.UUID.randomUUID() }
* header X-Trace-ID = getTraceId()
```gherkin
### Multiple Headers
```gherkin
# Set multiple headers with JSON
* headers { Accept: 'application/json', 'X-API-Version': '2.0' }
# Headers from variable
* def commonHeaders = {
'Accept': 'application/json',
'X-Client': 'karate-tests',
'X-Session-ID': sessionId
}
* headers commonHeaders
# Dynamic headers with null handling
* def optionalHeaders = {
'X-User-ID': userId,
'X-Debug': debugMode ? 'true' : null # null values are ignored
}
* headers optionalHeaders
```gherkin
### Global Headers Configuration
```gherkin
# Configure headers for all requests
* configure headers = { 'Accept': 'application/json', 'X-API-Version': '2.0' }
# Dynamic headers with function
* def headerFunction =
"""
function() {
var headers = {
'X-Request-ID': java.util.UUID.randomUUID() + '',
'X-Timestamp': new Date().getTime() + ''
};
if (karate.get('authToken')) {
headers['Authorization'] = 'Bearer ' + karate.get('authToken');
}
return headers;
}
"""
* configure headers = headerFunction
```gherkin
## Authentication Patterns
### Bearer Token Authentication
```gherkin
Background:
# Get authentication token
* url authUrl
* path '/auth/login'
* request { username: 'admin', password: 'secret' }
* method post
* status 200
* def authToken = response.token
Scenario: Use bearer token
* url apiUrl
* path '/protected/resource'
* header Authorization = 'Bearer ' + authToken
* method get
* status 200
```gherkin
### Basic Authentication
```gherkin
# Manual Basic Auth header
* def credentials = 'username:password'
* def encoded = java.util.Base64.encoder.encodeToString(credentials.bytes)
* header Authorization = 'Basic ' + encoded
# Using Karate's built-in support
* def auth = { username: 'admin', password: 'secret' }
* header Authorization = call read('classpath:auth/basic-auth.js') auth
```gherkin
### API Key Authentication
```gherkin
# Header-based API key
* header X-API-Key = apiKey
* header Api-Key = apiKey
# Query parameter API key
* param api_key = apiKey
* param access_key = apiKey
# Combined approach
Background:
* def apiKey = karate.properties['api.key'] || 'default-key'
* configure headers = { 'X-API-Key': '#(apiKey)' }
```gherkin
### OAuth 2.0 Authentication
```gherkin
Feature: OAuth 2.0 Authentication
Background:
* url oauthUrl
Scenario: Client credentials flow
* path '/oauth/token'
* header Content-Type = 'application/x-www-form-urlencoded'
* form field grant_type = 'client_credentials'
* form field client_id = clientId
* form field client_secret = clientSecret
* form field scope = 'read write'
* method post
* status 200
* def accessToken = response.access_token
* def tokenType = response.token_type
* def expiresIn = response.expires_in
Scenario: Use OAuth token
* url apiUrl
* path '/api/resource'
* header Authorization = tokenType + ' ' + accessToken
* method get
* status 200
```gherkin
### JWT Authentication
```gherkin
Feature: JWT Authentication
Background:
* def jwtSecret = 'your-secret-key'
* def createJWT = read('classpath:auth/jwt-utils.js')
Scenario: Generate and use JWT
* def payload = {
sub: '1234567890',
name: 'John Doe',
iat: new Date().getTime() / 1000,
exp: (new Date().getTime() / 1000) + 3600
}
* def jwt = createJWT(payload, jwtSecret)
* url apiUrl
* path '/protected'
* header Authorization = 'Bearer ' + jwt
* method get
* status 200
```gherkin
## Cookie Management
### Setting Cookies
```gherkin
# Individual cookies
* cookie sessionId = '12345'
* cookie preferences = 'theme=dark;lang=en'
# Multiple cookies
* cookies { sessionId: 'abc123', userId: '456', role: 'admin' }
# Dynamic cookies
* def sessionCookie = { name: 'SESSION', value: sessionId, domain: '.example.com' }
* cookie (sessionCookie.name) = sessionCookie.value
```gherkin
### Cookie Configuration
```gherkin
# Auto-manage cookies (default behavior)
* configure cookies = true
# Clear all cookies
* configure cookies = null
# Custom cookie handling
* def cookieJar = {}
* configure cookies = cookieJar
```gherkin
### Response Cookies
```gherkin
Scenario: Handle response cookies
* url loginUrl
* path '/auth/login'
* request { username: 'user', password: 'pass' }
* method post
* status 200
# Access response cookies
* def sessionCookie = responseCookies.sessionId
* match sessionCookie.value == '#string'
* match sessionCookie['max-age'] == '#number'
# Use cookie in next request
* url apiUrl
* path '/user/profile'
* cookie sessionId = sessionCookie.value
* method get
* status 200
```gherkin
## Advanced Authentication Patterns
### Token Refresh Pattern
```gherkin
Feature: Auto-refresh authentication
Background:
* def auth = callonce read('get-initial-token.feature')
* def token = auth.token
* def refreshToken = auth.refreshToken
Scenario: API call with token refresh
* url apiUrl
* path '/protected/resource'
* header Authorization = 'Bearer ' + token
* method get
# Handle token expiration
* if (responseStatus == 401) karate.call('refresh-token.feature', { refreshToken: refreshToken })
* if (responseStatus == 401) header Authorization = 'Bearer ' + newToken
* if (responseStatus == 401) retry until responseStatus == 200
```gherkin
### Multi-Factor Authentication
```gherkin
Feature: MFA Authentication Flow
Scenario: Login with MFA
# Step 1: Initial login
* url authUrl
* path '/auth/login'
* request { username: 'user', password: 'password' }
* method post
* status 200
* def sessionToken = response.sessionToken
* def mfaToken = response.mfaToken
# Step 2: Submit MFA code
* path '/auth/mfa/verify'
* header X-Session-Token = sessionToken
* request { mfaToken: mfaToken, code: '123456' }
* method post
* status 200
* def authToken = response.authToken
# Step 3: Access protected resource
* url apiUrl
* path '/secure/data'
* header Authorization = 'Bearer ' + authToken
* method get
* status 200
```gherkin
### Certificate-Based Authentication
```gherkin
# Configure SSL with client certificate
* configure ssl = {
keyStore: 'classpath:certs/client.p12',
keyStorePassword: 'password',
keyStoreType: 'pkcs12'
}
Scenario: Mutual TLS authentication
* url 'https://secure-api.example.com'
* path '/mtls/endpoint'
* method get
* status 200
```gherkin
## Security Best Practices
### Secure Token Storage
```gherkin
Background:
# Don't hardcode sensitive data
* def clientId = karate.properties['client.id']
* def clientSecret = karate.properties['client.secret']
* def apiKey = java.lang.System.getenv('API_KEY')
# Use secure token storage
* def tokenStore = {}
* def saveToken = function(token) { tokenStore.token = token; tokenStore.expiry = new Date().getTime() + 3600000 }
* def getToken = function() { return tokenStore.expiry > new Date().getTime() ? tokenStore.token : null }
```gherkin
### Header Security
```gherkin
# Security headers
* headers {
'X-Content-Type-Options': 'nosniff',
'X-Frame-Options': 'DENY',
'X-XSS-Protection': '1; mode=block',
'Strict-Transport-Security': 'max-age=31536000; includeSubDomains'
}
# CORS headers
* headers {
'Access-Control-Allow-Origin': '*',
'Access-Control-Allow-Methods': 'GET, POST, PUT, DELETE',
'Access-Control-Allow-Headers': 'Content-Type, Authorization'
}
```gherkin
### Authentication Helpers
```gherkin
# Reusable authentication feature
@ignore
Feature: Auth Helper
Scenario: Get auth token
* url authUrl
* path '/auth/token'
* header Authorization = 'Basic ' + encodedCredentials
* method post
* status 200
* def token = response.access_token
# Use in other features
Background:
* def auth = callonce read('auth-helper.feature')
* def authToken = auth.token
* configure headers = { 'Authorization': 'Bearer #(authToken)' }
```gherkin
## Debugging Authentication
### Request Inspection
```gherkin
# Log headers for debugging
* print 'Request headers:', karate.get('headers')
* print 'Auth header:', karate.request.header('Authorization')
# Conditional logging
* if (karate.env == 'dev') karate.log('Token:', authToken)
```gherkin
### Authentication Troubleshooting
```gherkin
Scenario: Debug authentication issues
* url apiUrl
* path '/debug/auth'
* header Authorization = 'Bearer ' + token
* method get
# Check various failure scenarios
* if (responseStatus == 401) print 'Authentication failed:', response
* if (responseStatus == 403) print 'Authorization failed:', response
* if (responseStatus == 401) match response contains { error: '#string' }
```gherkin
## Performance Optimization
### Token Caching
```gherkin
Background:
# Cache token for all scenarios
* def getAuthToken =
"""
function() {
var token = karate.get('cachedToken');
if (!token) {
var auth = karate.call('get-token.feature');
token = auth.token;
karate.set('cachedToken', token);
}
return token;
}
"""
* def authToken = getAuthToken()
```gherkin
### Connection Pooling
```gherkin
# Reuse authenticated connections
* configure reuseConnections = true
* configure maxConnections = 10
* configure connectionTimeout = 5000
```gherkin
## Next Steps
- Learn about [Request Body](/docs/http-requests/request-body) for complex payloads
- Explore [File Uploads](/docs/http-requests/file-uploads) for multipart requests
- Understand [Response Handling](/docs/http-responses/status-codes) for validation