Load Testing a Non-API Laravel Web Application with Sanctum Session-Based Authentication Using K6
Tags: laravel, k6, testing, session
Published: 2024-05-19 21:23:54

The idea for this post came from a project I handled at work, where I needed to load test a high-demand platform. I initially started with **Jmeter** based on colleagues' recommendations but encountered issues with Sanctum session authentication tokens. Despite multiple attempts, I couldn't resolve the problem.

The aim of this tutorial is not to introduce you to Load Testing or K6 but rather, to offer a solution for those facing similar issues with passing Sanctum session token in their tests, so they wouldn't go through the stress I experienced.
Upon researching about other alternatives to Jmeter, I discovered **K6**, an open-source load testing tool.

Testing an endpoint that required Sanctum session-based authentication proved challenging, particularly when handling the XSRF-TOKEN. I searched extensively for solutions on integrating Sanctum with K6 but found none. This led me to create my own approach, which I'm sharing here.

Below is the sample K6 test code and it is easy to understand for those with basic understanding of K6 and Javascript.

```
import { parseHTML } from 'k6/html';
import { sleep, group, check } from "k6";
import http from 'k6/http';

export const options = {
    stages: [
        { target: 50, duration: '1m' },
        { target: 100, duration: '0' },
        { target: 200, duration: '1m30s' },
    ],
}

// Login credentials
const jsonData = JSON.parse(open('./data.json')).users;

export default function main() {
    let response;
    let token;
    
    group('get login page', function () {
        response = http.get('https://your-domain/login');

        let xsrfTokenValue = null;
        let cookies = response.headers['Set-Cookie'];
        if (cookies) {
            let cookieArray = cookies.split(';');
            cookieArray.forEach(cookie => {
                if (cookie.includes('XSRF-TOKEN')) {
                    xsrfTokenValue = cookie.split('=')[1].replace(/%3D$/, ''); // Remove '=%3D' from the end
                }
            });
           
            token = xsrfTokenValue;
        }

        check(response, {
            'is status 200': (r) => r.status === 200,
            'XSRF-TOKEN exists': (t) => t !== null,
        });
    });

    sleep(10);
    
    group('post login page', function () {
        
        const payload = JSON.stringify({
            username: jsonData[0].username,
            password: jsonData[0].password,
        });

        const params = {
            headers: {
                Connection: 'keep-alive',
                'Content-Type': 'application/json',
                'X-XSRF-TOKEN': token,
            },
        };

        const res = http.post('https://your-domain/login', payload, params);
        check(res, {
            'is status 200': (r) => r.status === 200,
            'is correct URL': (r) => r.url === 'https://your-domain/welcome-page'
        });
    });

    sleep(10);
}
```
I hope this solution helps you overcome the challenges of handling Sanctum session-based authentication in your load testing.
If you have any questions or need further clarification, feel free to drop a comment. Happy testing!

Cheers!