Jsonwebtoken + webpack -> TypeError: Value is not an object: undefined

Hi team!

Im trying to use jsonwebtoken library with webpack 5 but it doesn’t seem to be working. After configuring webpack config I was able to build the bundle and just importing this import jwt from 'jsonwebtoken'; works fine.

even so when I try to execute the bundle I get this error when I use jwt.sign function inside the script:

➜  k6-template-es6 git:(main) ✗ ./k6 run dist/faker-test.js

          /\      |‾‾| /‾‾/   /‾‾/   
     /\  /  \     |  |/  /   /  /    
    /  \/    \    |     (   /   ‾‾\  
   /          \   |  |\  \ |  (‾)  | 
  / __________ \  |__| \__\ \_____/ .io

     execution: local
        script: dist/faker-test.js
        output: -

     scenarios: (100.00%) 1 scenario, 1 max VUs, 10m30s max duration (incl. graceful stop):
              * default: 1 iterations for each of 1 VUs (maxDuration: 10m0s, gracefulStop: 30s)

ERRO[0000] TypeError: Value is not an object: undefined

I have use this repo as base to do this POC → GitHub - grafana/k6-template-es6: Template using Webpack and Babel to enable ES6 features in k6 tests

This is the test script:

import jwt from 'jsonwebtoken';

const TEST_JWT_KEY = {
    algorithm: 'ES256',
    issuer: 'test',
    pkcs8: '-----BEGIN PRIVATE KEY-----\nsome_key\n-----END PRIVATE KEY-----\n',
};

const userData = {
    iss: TEST_JWT_KEY.issuer,
    'srt:driver_id': 12345,
    iat: Date.now(),
};

function generateJWT(payload) {
    const privateKey = TEST_JWT_KEY.pkcs8;
    const algorithm = TEST_JWT_KEY.algorithm;
    const token = jwt.sign(payload, privateKey, { algorithm: 'ES256' });
    return token;
}

export default function () {
  const token = generateJWT(userData);
  console.log(token)
}

This is my webpack config just in case :

var webpack = require("webpack");
const { CleanWebpackPlugin } = require("clean-webpack-plugin");
var path = require("path");
const GlobEntries = require("webpack-glob-entries");

module.exports = {
  mode: "production",
  entry: GlobEntries("./src/*-test.js"), // Generates multiple entry for each test
  output: {
    path: path.resolve(__dirname, "dist"),
    libraryTarget: "commonjs",
    filename: "[name].js",
  },
  module: {
    rules: [
      {
        test: /\.js$/,
        loader: "babel-loader",
        // by default, it resolves `node_modules`
      },
    ],
  },
  stats: {
    colors: true,
  },
  plugins: [
    new CleanWebpackPlugin(),
    new webpack.ProvidePlugin({
      process: "process/browser",
    }),
    new webpack.ProvidePlugin({
      Buffer: ['buffer', 'Buffer'],
  }),
  ],
  externals: /^(k6|https?\:\/\/)(\/.*)?/,
  resolve: {
    fallback: {
      buffer: require.resolve("buffer/"),
      crypto: require.resolve("crypto-browserify"),
      stream: require.resolve("stream-browserify"),
      util: require.resolve("util/"),
      process: require.resolve("process"),
      buffer: require.resolve('buffer/'),
    },
  },
};

Any idea about what is going on?
Thanks in advance!

Hi @hernanmateikastuart :wave:

I’m not familiar with the jsonwebtoken library myself. Still, my intuition is that the library relies on the WebCrypto API to perform the jwt signature (as I see in the code) and expects to have the ES256 (ECDSA) algorithm available in the runtime to do so.

Unfortunately, k6’s implementation of the WebCrypto API is still experimental and partial and doesn’t support the ECDSA algorithms in the context of signature yet.

We have an issue open for it, and we would really appreciate it if you could take the time to add a :+1: to it to let us know this is something you care to see land in k6. If you have the resources, capacity, and skills for it, please also consider contributing PR implementing support for it, that would be very much appreciated.

Let me know if that’s helpful, and if I can help any further :bowing_man:

1 Like