Skip to main content

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' }

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
Windows Authentication

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