DEV Community

Shamsuddeen Abdulkadir
Shamsuddeen Abdulkadir

Posted on

Load Testing a Non-API Laravel Web Application with Sanctum Session-Based Authentication Using K6

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);
}
Enter fullscreen mode Exit fullscreen mode

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!

Top comments (2)

Collapse
 
peace_time_c9cca854860c66 profile image
Peace Time

If getting XSRF TOKEN from cookies. What if the request does regenerates toke by default. I think you'd have to refresh page before cookies retrieve new token.

Collapse
 
eldeeno profile image
Shamsuddeen Abdulkadir • Edited

In scenarios where the token regenerates frequently, it is essential to ensure the token used for subsequent requests is always up-to-date. That is why in the example script, the token variable is globally accessible to every request block (group()) and gets set by the first request and used in subsequent ones.