Search code examples
javascriptoauthload-testingk6

Validating Oauth credentials in K6 load test script


I am trying to grab a token and pass it into the GET requests.

The below works, but it's grabbing a token every single time a request runs. Ideally I want to grab it once per run and pass it to the requests.

Any ideas on how to make that happen from the below code?

import http from "k6/http";
import { sleep } from "k6";
import { check } from "k6";
import { htmlReport } from "https://raw.githubusercontent.com/benc-uk/k6-reporter/main/dist/bundle.js";

export let options = {
  insecureSkipTLSVerify: true,
  noConnectionReuse: false,
  vus: 5,
  duration: "10s",
};

  
var client_id = "clientId123";
var secret = "secret123";
var scope = "scope123";


export default () => {

  var body =
  "grant_type=client_credentials&client_id=" +
  client_id +
  "&client_secret=" +
  secret +
  "&scope=" +
  scope;

  var tokenResponse = http.post( "https://login.microsoftonline.com/tenantID123/oauth2/v2.0/token", body, { headers: { ContentType: "application/x-www-form-urlencoded"}});
  var result = JSON.parse(tokenResponse.body);
  var token = result.access_token;

   check(tokenResponse, {
    'is status 200': (r) => r.status === 200
   })

  var resp1 = http.get("url_1", {
    headers: { Authorization: `Bearer ${token}` },
  });
  var resp2 = http.get("url_2", {
    headers: { Authorization: `Bearer ${token}` },
  });

  check(resp1, {
      'is status 200': (r) => r.status === 200,
    })
    check(resp2, {
      'is status 200': (r) => r.status === 200,
    })

};

Solution

  • In k6 lifecycle there are 4 stages. You need to use the proper one for your need.

    Get exactly one token for the whole test

    Can use setup function

    export function setup(){
      var client_id = "clientId123";
      var secret = "secret123";
      var scope = "scope123";
    
      var body =
        "grant_type=client_credentials&client_id=" +
        client_id +
        "&client_secret=" +
        secret +
        "&scope=" +
        scope;
    
      var tokenResponse = http.post(
        "https://login.microsoftonline.com/tenantID123/oauth2/v2.0/token",
        body,
        { headers: { ContentType: "application/x-www-form-urlencoded" } }
      );
      var result = JSON.parse(tokenResponse.body);
      var token = result.access_token;
    
      return {token}
    }
    
    export default (data) => {
        var token = data.token;
        // Rest ...
    
    }
    

    Get one token for every VU (Virtual User)

    Can use "init code."

    // ...
    var body =
    "grant_type=client_credentials&client_id=" +
    client_id +
    "&client_secret=" +
    secret +
    "&scope=" +
    scope;
    
    var tokenResponse = http.post(
    "https://login.microsoftonline.com/tenantID123/oauth2/v2.0/token",
    body,
    { headers: { ContentType: "application/x-www-form-urlencoded" } }
    );
    var result = JSON.parse(tokenResponse.body);
    var token = result.access_token;
    
    export default () => {
      var resp1 = http.get("url_1", {
        headers: { Authorization: `Bearer ${token}` },
      });
      // ...
    };