HTTP REQUESTS
Headers and Authentication
Set headers and implement authentication patterns including bearer tokens, OAuth 2.0, JWT, and certificate-based security for comprehensive API testing.
Simple Header
Set individual headers using the header
keyword for straightforward request configuration.
Scenario: Add single header
Given url 'https://api.example.com'
And path 'users'
And header Accept = 'application/json'
When method get
Then status 200
Multiple Headers
Use the headers
keyword with a JSON object to set multiple headers simultaneously.
Scenario: Set multiple headers at once
Given url 'https://api.example.com'
And path 'users'
And headers { Accept: 'application/json', X-API-Version: '2.0' }
When method get
Then status 200
And match responseHeaders['Content-Type'][0] contains 'application/json'
Headers can be defined as variables for reuse across scenarios.
Background:
* def commonHeaders = { Accept: 'application/json', X-Client: 'karate-tests' }
Scenario: Use predefined headers
Given url 'https://api.example.com'
And path 'users'
And headers commonHeaders
When method get
Then status 200
Dynamic Headers
Embed expressions in headers using string concatenation or the #()
syntax for runtime values.
Background:
* def userId = 12345
* def sessionId = 'abc-123-def'
Scenario: Headers with embedded expressions
Given url 'https://api.example.com'
And path 'users', userId
And header Authorization = 'Bearer ' + authToken
And header X-Session-ID = sessionId
And header X-Request-ID = java.util.UUID.randomUUID()
When method get
Then status 200
Null values in header objects are automatically ignored.
Scenario: Optional headers with null handling
* def debugMode = false
* def optionalHeaders = { X-User-ID: '123', X-Debug: debugMode ? 'true' : null }
Given url 'https://api.example.com'
And headers optionalHeaders
When method get
Then status 200
Basic Authentication
Implement HTTP Basic Authentication using base64-encoded credentials in the Authorization header.
Scenario: Basic auth with manual encoding
* def credentials = 'admin:secret'
* def encoded = Java.type('java.util.Base64').encoder.encodeToString(credentials.bytes)
Given url 'https://api.example.com'
And path 'protected'
And header Authorization = 'Basic ' + encoded
When method get
Then status 200
Bearer Token
Use bearer tokens for modern API authentication by adding the token to the Authorization header.
Background:
# Obtain token from login endpoint
* url 'https://auth.example.com'
* path 'auth/login'
* request { username: 'admin', password: 'secret' }
* method post
* status 200
* def authToken = response.token
Scenario: Access protected resource with bearer token
Given url 'https://api.example.com'
And path 'protected/resource'
And header Authorization = 'Bearer ' + authToken
When method get
Then status 200
API Key Authentication
Pass API keys via headers or query parameters depending on the API specification.
Background:
* def apiKey = karate.properties['api.key'] || 'default-key'
Scenario: Header-based API key
Given url 'https://api.example.com'
And path 'data'
And header X-API-Key = apiKey
When method get
Then status 200
Scenario: Query parameter API key
Given url 'https://api.example.com'
And path 'data'
And param api_key = apiKey
When method get
Then status 200
OAuth 2.0 Client Credentials
Implement OAuth 2.0 client credentials flow for server-to-server authentication.
Background:
* def clientId = karate.properties['oauth.client.id']
* def clientSecret = karate.properties['oauth.client.secret']
Scenario: Obtain OAuth token
Given url 'https://oauth.example.com'
And path 'oauth/token'
And header Content-Type = 'application/x-www-form-urlencoded'
And form field grant_type = 'client_credentials'
And form field client_id = clientId
And form field client_secret = clientSecret
And form field scope = 'read write'
When method post
Then status 200
And def accessToken = response.access_token
Scenario: Use OAuth token
Given url 'https://api.example.com'
And path 'api/resource'
And header Authorization = 'Bearer ' + accessToken
When method get
Then status 200
JWT Authentication
Generate and use JSON Web Tokens for stateless authentication with custom claims.
Background:
* def jwtSecret = karate.properties['jwt.secret']
* def createJWT = read('classpath:auth/jwt-utils.js')
Scenario: Create and validate JWT
* def payload = { sub: '1234567890', name: 'John Doe', exp: (new Date().getTime() / 1000) + 3600 }
* def jwt = createJWT(payload, jwtSecret)
Given url 'https://api.example.com'
And path 'protected'
And header Authorization = 'Bearer ' + jwt
When method get
Then status 200
And match response contains { userId: '#string' }
Cookie Management
Set and manage cookies for session-based authentication and tracking.
Scenario: Set individual cookies
Given url 'https://api.example.com'
And path 'users'
And cookie sessionId = '12345'
And cookie preferences = 'theme=dark;lang=en'
When method get
Then status 200
Scenario: Set multiple cookies
* def cookies = { sessionId: 'abc123', userId: '456', role: 'admin' }
Given url 'https://api.example.com'
And path 'profile'
And cookies cookies
When method get
Then status 200
Extract and reuse cookies from server responses.
Scenario: Handle response cookies
Given url 'https://auth.example.com'
And path 'auth/login'
And request { username: 'user', password: 'pass' }
When method post
Then status 200
And def sessionCookie = responseCookies.sessionId
And match sessionCookie.value == '#string'
# Use cookie in subsequent request
Given url 'https://api.example.com'
And path 'user/profile'
And cookie sessionId = sessionCookie.value
When method get
Then status 200
Advanced: NTLM Authentication
Authenticate with Windows domain servers using NTLM protocol for enterprise systems.
Background:
* def ntlmUser = karate.properties['ntlm.username'] || java.lang.System.getenv('NTLM_USER')
* def ntlmPass = karate.properties['ntlm.password'] || java.lang.System.getenv('NTLM_PASS')
* def ntlmDomain = karate.properties['ntlm.domain'] || 'CORP'
* configure ntlmAuth = { username: '#(ntlmUser)', password: '#(ntlmPass)', domain: '#(ntlmDomain)' }
Scenario: Access Windows-authenticated resource
Given url 'https://windows-server.corp.example.com'
And path 'sharepoint/api/documents'
When method get
Then status 200
NTLM is commonly used for authenticating with Windows-based services and Active Directory environments. Store credentials securely using environment variables or Java system properties rather than hardcoding them in feature files.
Advanced: Certificate Authentication
Configure mutual TLS authentication using client certificates for enhanced security.
Background:
* configure ssl = { keyStore: 'classpath:certs/client.p12', keyStorePassword: 'password', keyStoreType: 'pkcs12' }
Scenario: Mutual TLS authentication
Given url 'https://secure-api.example.com'
And path 'mtls/endpoint'
When method get
Then status 200
And match response contains { authenticated: true }
Advanced: Multi-Factor Authentication
Implement multi-step authentication flows including MFA verification.
Scenario: Login with MFA
# Step 1: Initial login
Given url 'https://auth.example.com'
And path 'auth/login'
And request { username: 'user', password: 'password' }
When method post
Then status 200
And def sessionToken = response.sessionToken
And def mfaToken = response.mfaToken
# Step 2: Submit MFA code
Given path 'auth/mfa/verify'
And header X-Session-Token = sessionToken
And request { mfaToken: '#(mfaToken)', code: '123456' }
When method post
Then status 200
And def authToken = response.authToken
# Step 3: Access protected resource
Given url 'https://api.example.com'
And path 'secure/data'
And header Authorization = 'Bearer ' + authToken
When method get
Then status 200
Advanced: Token Refresh
Implement automatic token refresh for long-running test sessions.
Background:
* def auth = callonce read('get-initial-token.feature')
* def token = auth.token
* def refreshToken = auth.refreshToken
Scenario: API call with token refresh
Given url 'https://api.example.com'
And path 'protected/resource'
And header Authorization = 'Bearer ' + token
When method get
Then status 200
# Refresh token if expired
* if (responseStatus == 401) karate.call('refresh-token.feature', { refreshToken: '#(refreshToken)' })
Security Best Practices
Store sensitive credentials securely using environment variables and system properties.
Background:
# Load credentials from secure sources
* def clientId = karate.properties['client.id']
* def clientSecret = karate.properties['client.secret']
* def apiKey = java.lang.System.getenv('API_KEY')
# Token storage with expiry tracking
* def tokenStore = {}
* def saveToken = function(token, expiry) { tokenStore.token = token; tokenStore.expiry = expiry }
* def getToken = function() { return tokenStore.expiry > new Date().getTime() ? tokenStore.token : null }
Create reusable authentication helpers for consistent token management across features.
# auth-helper.feature
@ignore
Feature: Auth Helper
Scenario: Get auth token
Given url authUrl
And path 'auth/token'
And header Authorization = 'Basic ' + encodedCredentials
When method post
Then status 200
And 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)' }
Next Steps
- Send request data: Request Parameters
- Upload files: Multipart Requests
- Make API calls: Making Requests