Skip to main content

Using a CSV file for login credentials and extracting the token from the response when running JMeter tests

Using a CSV file for login credentials and extracting the token from the response when running JMeter tests

Key takeaways

  • A CSV of credentials gives each virtual user a distinct login, which is what makes auth load realistic.
  • Extract the token with a post-processor on the login request (JSON Extractor for a JSON body, Regular Expression Extractor for a header or HTML) and set its match number to 1.
  • JMeter variables are local to a thread, so every virtual user carries its own token. Use test accounts only, since tokens and credentials end up in result files.

To log JMeter virtual users in from a CSV file and reuse the token, read username,password rows with a CSV Data Set Config, send ${username} and ${password} in the login HTTP Request, add a JSON Extractor to that request to save the token into a variable, and send ${token} in an HTTP Header Manager on the requests that need a logged-in user. Each thread then logs in as a different user and keeps its own token.

How does the CSV login flow fit together?

The test plan needs five elements: a CSV Data Set Config that reads the credentials, a login request that sends them, a post-processor that pulls the token out of the response, the protected requests, and a Header Manager that attaches the token to them. JMeter runs a post-processor right after the sampler it belongs to, so the token is in place before the next request starts.

Test Plan
└── Thread Group
    ├── CSV Data Set Config        (username,password)
    ├── HTTP Cookie Manager
    ├── login_user                 HTTP Request, POST /apis/login
    │   └── JSON Extractor         token <- $.data.id
    └── call UI with user logged in
        └── HTTP Header Manager    X-CSRF-Token: ${token}

The screenshots below come from JMeter 2.12 and the original version of this article, so some element names differ from JMeter 5.6.3; the text gives the current names. The order in which JMeter runs config elements, samplers and post-processors is explained in the execution order of elements in JMeter.

Step 1: Prepare the CSV file with the credentials

Put one account per line, username first, then password:

user1,password1
user2,password2
user3,password3
user4,password4
user5,password5

Use dedicated test accounts, never real customer logins. Save the file next to the .jmx and reference it by a relative name such as login_credentials.csv. JMeter resolves relative file names against the test plan’s folder, while an absolute path like the /home/ubuntu/login_credentials.txt in the screenshot is unlikely to work on another machine. If you prefer a header line (username,password) at the top of the file, leave Variable Names empty and JMeter reads the names from it.

Step 2: Add the CSV Data Set Config

Right-click the Thread Group and choose Add > Config Element > CSV Data Set Config. The screenshot adds it under the login request; placing it directly under the Thread Group makes its scope obvious.

Add > Config Element > CSV Data Set Config menu on the login_user HTTP Request

Fill in Filename, set Variable Names to username,password and Delimiter to ,.

CSV Data Set Config with the filename and the variable names username,password

Two behaviours matter for logins. First, with the default sharing mode (All threads) the file is opened once and each thread takes a different line. Second, JMeter reads a new line at the start of every iteration, so a thread that loops logs in as a different user each time round. If the application allows only one session per account, give every thread a unique row: set Recycle on EOF to False, Stop thread on EOF to True and provide at least as many rows as you expect logins. Every field is explained in our CSV Data Set Config guide.

Step 3: Send the credentials in the login request

Add an HTTP Request for the login (login_user in the screenshots), set the method to POST and the path to your login endpoint, and send the CSV values as parameters: username with the value ${username} and password with ${password}. If the endpoint expects JSON, put the body in Body Data instead, for example {"username":"${username}","password":"${password}"}, and add a Header Manager with Content-Type: application/json.

Add an HTTP Cookie Manager to the Thread Group as well. JMeter’s documentation says each thread gets its own cookie storage, so if the application also sets a session cookie at login, every virtual user keeps its own session.

Step 4: Extract the token with a JSON Extractor

Suppose the login response looks like this, with the token in data.id:

{
  "data": {
    "id": "a964a723ecfb61ba5e54d8cd22420f20"
  },
  "status": {
    "httpStatus": 200,
    "success": true
  }
}

Right-click the login request and add Post Processors > JSON Extractor. The original screenshots show jp@gc - JSON Path Extractor, which came with the old JMeterPlugins-ExtrasLibs set and which jmeter-plugins.org now marks as deprecated in favour of the extractor built into JMeter; the settings map one to one.

Add > Post Processors menu with jp@gc - JSON Path Extractor selected

  • Names of created variables: token
  • JSON Path Expressions: $.data.id, the path to the token in your response. Adjust it to your JSON.
  • Match No.: 1. The default, 0, picks a random match, which only goes unnoticed while the path matches a single value.
  • Default Values: TOKEN_NOT_FOUND, so a failed login shows up as an obviously wrong header instead of a silently empty one.

JSON Path Extractor saving $.data.id into the token variable with the default no-token

What if the token is not in a JSON body?

Use a Regular Expression Extractor on the login request instead. It can read the body, the response headers or the URL. For a token returned in a response header, set Field to check to Response Headers and use:

  • Name of created variable: token
  • Regular Expression: X-CSRF-Token: (\S+)
  • Template: $1$
  • Match No.: 1
  • Default Value: TOKEN_NOT_FOUND

For a token in an HTML form, keep Field to check on Body and match the hidden field, for example name="csrf_token" value="([^"]+)". The expression needs one pair of parentheses around the part you want to keep, and you write it without enclosing slashes. The other extractors, and how to choose between them, are covered in correlation in JMeter.

Step 5: Send the token with every later request

Add the requests that need a logged-in user and give them an HTTP Header Manager with the header your application expects. The example uses X-CSRF-Token with the value ${token}; an API that uses bearer tokens takes Authorization with Bearer ${token}. Put the Header Manager under a single request to scope it to that request, or under the Thread Group to send it with every request in the group. JMeter merges several Header Managers, so you can keep common headers at the top and add the token where it is needed.

HTTP Request call UI with user logged in, with an HTTP Header Manager under it

In the screenshot the path sits in the Server Name or IP field; put the host name there and the path in Path.

HTTP Header Manager sending X-CSRF-Token with the value ${token}

Every other request that needs the login works the same way: reference ${token} in its header.

How do you check that each user gets its own token?

Run the plan with two or three threads and a View Results Tree listener. For each thread, open the login sample and confirm the response holds a token, then open the next request’s Request tab and check that the header carries a real value. If you see TOKEN_NOT_FOUND, the JSON path or regular expression did not match; if you see the literal text ${token}, the extractor never ran or the variable name differs. A Response Assertion on the protected request (for example, the page contains the user’s name) catches a token that is present but rejected.

Because JMeter variables are local to a thread, every virtual user keeps the token from its own login. That is the main difference from the OAuth 2.0 client-credentials setup in JMeter, where one token is fetched once and shared by all threads through a property. Remove View Results Tree before the real run: JMeter’s best practices reserve it for debugging. The JMeter load testing tutorial shows how to run the finished plan from the command line and read the report.

How do you log in only once per thread?

Wrap the login request in a Once Only Controller. JMeter then runs it on the first iteration of each thread and skips it afterwards, which its documentation suggests for tests that require a login. The token stays in the thread’s variables for the rest of the test. Note that the CSV Data Set still reads a new line each iteration, so do not send ${username} on later requests if you expect it to match the logged-in account. For more patterns with CSV data, such as random rows and per-thread files, see using CSV data in JMeter tests.

Running the CSV login test in the cloud

A test that reads a credentials file needs that file wherever the load runs. LoadFocus JMeter load testing runs an uploaded .jmx from 25 cloud regions, and the product page says you upload CSV data files with the plan. Keep the file name relative in the CSV Data Set Config so the plan finds it there, and make sure the file has enough test accounts for the number of virtual users you run.

Frequently Asked Questions

Why give each virtual user its own login?

Because a single shared account does not behave like real traffic. Sessions, rate limits and per-user caches all serve one login far more cheaply than they serve a thousand, so the test understates the load.

How do I get the token out of the login response?

With a post-processor on the login sampler: the JSON Extractor for a JSON body, or the Regular Expression Extractor for a header or an HTML field. It writes the token into a variable that later requests reference with the ${name} syntax.

Why does my request send TOKEN_NOT_FOUND or ${token}?

TOKEN_NOT_FOUND is the default value, so the extractor ran but the JSON path or regular expression matched nothing; compare it with the actual response in View Results Tree. A literal ${token} means the variable was never set, usually because the extractor is attached to a different request or the variable name is spelled differently.

Do I still need the JMeterPlugins-Extras plugins for this?

No. Earlier versions of this article required them for the JSON Path Extractor. JMeter now has a built-in JSON Extractor, and the CSV Data Set Config, Regular Expression Extractor and HTTP Header Manager have always been part of JMeter.

Is it safe to put real credentials in the CSV?

No. Use dedicated test accounts. The CSV sits next to the test plan and the values end up in result files and logs, which are shared and archived far more widely than a password should be.

Sources

  • Apache JMeter component reference: CSV Data Set Config, JSON Extractor, Regular Expression Extractor, HTTP Header Manager, HTTP Cookie Manager, Once Only Controller, jmeter.apache.org/usermanual/component_reference.html (October 2026)
  • Apache JMeter functions and variables (“Variables are local to a thread”), jmeter.apache.org/usermanual/functions.html (October 2026)
  • Apache JMeter best practices, jmeter.apache.org/usermanual/best-practices.html (October 2026)
  • JMeter Plugins catalog, JSON/YAML Plugins marked deprecated in favour of core JMeter, jmeter-plugins.org/repo (October 2026)
  • LoadFocus JMeter load testing page, loadfocus.com/jmeter-load-testing (October 2026)

Chris

Head of Content at LoadFocus

Chris leads content and oversees development across the services this blog covers. The guides and tool comparisons here come out of the same decisions that shape what ships.

Weekly tips right in your inbox.

Don’t miss out on the latest testing tips and tricks, tools and news related to software testing.

Already +20,000 members in the list.

The Load Testing Platform with AI That Explains Your Results

Load test websites and APIs from 25 cloud regions, monitor page speed and uptime, and get AI analysis that explains your results in plain English.

Cloud load testing, website speed and API monitoring in one place.

Hi there! Can I share a cool thing I'm working on with you?

A software testing newsletter that sparks joy.

Our goal is to create helpful content for software developers and testers.

If you're not into it, you can unsubscribe instantly.