Docs
Authentication Workflow Tutorial
Learn how to test authentication flows with login, token capture, and authenticated requests using Quadrastack workflows.
Authentication Workflow Tutorial
Learn how to test authentication flows by chaining requests together. This tutorial covers login flows, token capture, and using session data in subsequent requests.
Time: 15 minutes | Level: Intermediate
What You'll Build
A complete authentication workflow that:
- Logs in and captures a token
- Uses the token to fetch user profile
- Updates user data with authenticated requests
- Validates each step with assertions
Prerequisites
- Completed First API Test tutorial
- Understanding of REST API authentication
- 15 minutes
Understanding Workflows
Workflows in Quadrastack allow you to:
- Execute requests in sequence
- Capture data from responses using
setVars - Pass data between steps with
{{.session.stepName.body.field}} - Build complex multi-step test scenarios
Step 1: Create Project Structure
Create a new directory:
mkdir auth-workflow-tutorial
cd auth-workflow-tutorial
Step 2: Set Up a Mock Authentication Server
First, let's create a mock API that simulates authentication. Create mocks.yaml:
mockServer:
auth-api:
description: Mock authentication API
listen: ":8080"
defaults:
status: 200
headers:
Content-Type: application/json
mocks:
login-route:
server: auth-api
description: Login endpoint that returns a token
match:
method: POST
path: /api/auth/login
respond:
- body: |
{
"success": true,
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9",
"userId": "user-12345",
"expiresIn": 3600
}
get-profile-route:
server: auth-api
description: Get user profile (requires auth token)
match:
method: GET
path: /api/user/profile
headers:
Authorization: "Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9"
respond:
- body: |
{
"userId": "user-12345",
"username": "johndoe",
"email": "john@example.com",
"role": "admin"
}
update-profile-route:
server: auth-api
description: Update user profile (requires auth token)
match:
method: PUT
path: /api/user/profile
headers:
Authorization: "Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9"
respond:
- body: |
{
"success": true,
"message": "Profile updated successfully",
"userId": "user-12345"
}
Step 3: Create Individual Requests
Create requests.yaml with individual request definitions:
requests:
login:
description: Authenticate user and get token
method: POST
url: http://localhost:8080/api/auth/login
headers:
Content-Type: application/json
body:
username: "johndoe"
password: "secret123"
expect:
status: 200
body:
$.success: true
$.token: exists
$.userId: exists
$.expiresIn: "> 0"
get-profile:
description: Fetch user profile with auth token
method: GET
url: http://localhost:8080/api/user/profile
headers:
Authorization: "Bearer {{.session.login.body.token}}"
expect:
status: 200
body:
$.userId: exists
$.username: !empty
$.email: matches "^[\\w.]+@[\\w.]+"
update-profile:
description: Update user profile with auth token
method: PUT
url: http://localhost:8080/api/user/profile
headers:
Authorization: "Bearer {{.session.login.body.token}}"
Content-Type: application/json
body:
username: "johndoe_updated"
email: "john.updated@example.com"
expect:
status: 200
body:
$.success: true
$.message: contains "successfully"
Step 4: Create the Workflow
Now create workflows.yaml to chain these requests together:
workflows:
auth-flow:
description: Complete authentication workflow
labels: ["auth", "integration"]
steps:
- request: login
out: login
- request: get-profile
# Uses token from {{.session.login.body.token}}
- request: update-profile
# Uses token from {{.session.login.body.token}}
**Key workflow concepts:**
- `out` - Captures the entire response into a session variable (e.g., `login`)
- `{{.session.login.body.token}}` - Access captured data from previous steps
- Requests reference session data directly in their definitions
## Step 5: Start Mock Server and Run Workflow
First, start the mock server in one terminal:
```bash
quadrastack --mock-server auth-api
Expected Output:
Mock server 'auth-api' started on :8080
Press Ctrl+C to stop
In another terminal, run the workflow:
quadrastack --workflow auth-flow
Expected Output:
Running workflow: auth-flow
✓ Step 1: login (200 OK, 3ms)
✓ Captured output 'login'
✓ Step 2: get-profile (200 OK, 2ms)
✓ Step 3: update-profile (200 OK, 2ms)
Workflow completed: 3/3 steps passed
Step 8: Handling Authentication Errors
Add error handling to your workflow. Update requests.yaml:
requests:
login-invalid:
description: Test invalid credentials
method: POST
url: http://localhost:8080/api/auth/login
headers:
Content-Type: application/json
body:
username: "invalid"
password: "wrong"
expect:
status: 401
body:
$.success: false
$.error: exists
get-profile-unauthorized:
description: Test unauthorized access
method: GET
url: http://localhost:8080/api/user/profile
headers:
Authorization: "Bearer invalid-token"
expect:
status: 401
Add mock responses for errors in mocks.yaml:
mocks:
login-invalid-route:
server: auth-api
description: Handle invalid credentials
match:
method: POST
path: /api/auth/login
body:
$.username: "invalid"
respond:
- status: 401
body: |
{
"success": false,
"error": "Invalid credentials"
}
unauthorized-route:
server: auth-api
description: Handle invalid token
match:
method: GET
path: /api/user/profile
headers:
Authorization: contains "invalid-token"
respond:
- status: 401
body: |
{
"error": "Unauthorized",
"message": "Invalid or expired token"
}
Step 9: OAuth 2.0 Flow Example
Here's a more complex OAuth-style flow:
workflows:
oauth-flow:
description: OAuth 2.0 authentication flow
steps:
# Step 1: Get authorization code
- request: get-auth-code
out: authCodeStep
# Step 2: Exchange code for token
# Request 'exchange-token' must use {{.session.authCodeStep.body.code}}
- request: exchange-token
out: tokenStep
# Step 3: Use access token
# Request 'get-protected-resource' must use {{.session.tokenStep.body.access_token}}
- request: get-protected-resource
# Step 4: Refresh token if needed
# Request 'refresh-token' must use {{.session.tokenStep.body.refresh_token}}
- request: refresh-token
Final Project Structure
auth-workflow-tutorial/
├── mocks.yaml
├── requests.yaml
├── workflows.yaml
└── vars.yaml
What You Learned
- Creating workflows with sequential steps
- Capturing response data with
setVars - Accessing session data with
{{.session.stepName.body.field}} - Passing data between workflow steps
- Testing authentication flows (login, token, authenticated requests)
- Handling authentication errors
- Building complex multi-step scenarios
Advanced Patterns
Pattern 1: Conditional Workflows
Pattern 1: Conditional Logic (Future)
Currently, you can use labels and separate scenarios to handle conditional flows.
Pattern 2: Token Refresh Flow
workflows:
auto-refresh:
steps:
- request: login
out: login
- request: api-call-1
# Uses {{.session.login.body.token}}
# If token expires, refresh it
# Request 'refresh-token' uses {{.session.login.body.refreshToken}}
- request: refresh-token
out: refresh
- request: api-call-2
# Uses {{.session.refresh.body.token}}
Next Steps
- Mock Server Setup - Deep dive into mock servers
- Workflows Guide - Complete workflow documentation
- Variables Guide - Advanced templating techniques
- Load Testing - Test auth flows under load
Common Issues
Token Not Captured
Token Not Captured
If {{.session.login.body.token}} is empty, check the response structure:
# Use verbose mode to see full response
quadrastack --workflow auth-flow --verbose
Session Variable Not Found
Ensure the step name matches:
# Step name is "login" (from out property or default if supported)
- request: login
out: login
# Reference must use "login"
- request: get-profile
# Definition uses {{.session.login.body.token}}
Mock Server Not Responding
Make sure the mock server is running and ports match:
# Start mock server
quadrastack --mock-server auth-api
# Check if it's listening
curl http://localhost:8080/api/auth/login
Tips
- Always validate tokens exist - Add
$.token: existsassertions - Use descriptive step names - Makes session variables easier to reference
- Test error cases - Invalid credentials, expired tokens, unauthorized access
- Start with mocks - Test your workflow logic before using real APIs
- Use verbose mode - Helps debug session variable issues
You now know how to build complex authentication workflows with Quadrastack!