Skip to Content
Technical Articles
Author's profile photo Andrei Vishnevsky

CSRF token in Postman. One click to get it and use it.

This blog is inspired by an excellent blog “Just a single click to test SAP OData Service which needs CSRF token validation” authored by Jerry Wang

I liked the approach Jerry shared. Each time you need to create, update or delete some data via (SAP) oData API you need to use CSRF token (e.g. it’s applicable to C4C oData API). It used to be quite a pain in Postman. Jerry suggested using an environment variable in Postman to share CSRF token between 2 (or more) requests. Where the first request is getting CSRF token for you and stores it in an environment variable while subsequent requests consume this CSRF token via the variable. Sounds logical.

However, in my case, the need to run a collection (of requests) each time when I need to do a quick and simple POST or PUT or PATCH to C4C oData API was not something I would be comfortable with.

I would prefer “real one-click”. Just hit the Send button in Postman and here we go. Something similar to OData Explorer tool available in C4C system where you don’t need to care about CSRF token at all. Frankly, it’s a great tool, but it has some performance issues when you launching it or navigating from one “heavy” entity type to another. And the error handling is another question which, in my opinion, oData Explorer needs to address to show the complete error message produced by the backend of C4C.

Postman beast is still a preference of mine.
So I wanted to improve Jerry’s approach to make it a “real one-click”.

A bit of research and play with Postman on one of business trips’ flights got me to the idea. And the idea was to use Pre-requests Script in Postman. They are powerful. As powerful as Test scripts. Or even more.

Here is the pre-request script I’ve put together. Console logs are there just for test purposes. Feel free to remove them if you’re clear on what the script is doing and when. You can see those logs in Postman Console if you open it before doing the call to your oData API. Postman Console is available either via menu View -> Show Postman Console or hotkey Alt+Ctrl+C.

console.log('Pre-request Script from Request start');

// We don't need to do anything if it's GET or x-csrf-token header is explicitly presented
if (pm.request.method !== 'GET' && !(pm.request.headers.has('x-csrf-token'))) {

  var csrfRequest = pm.request.clone();
  csrfRequest.method = 'GET';
  if (pm.request.method === 'POST') {
    // for POST method usually it is ....<something>Collection in the URL
    // so we add $top=1 just to quickly get csrf token; 
    // for PUT, PATCH or DELETE the same URL would be enough,
    // because it points to the actual entity
    csrfRequest.url = pm.request.url + '?$top=1';
  }

  csrfRequest.upsertHeader({
    key: 'x-csrf-token',
    value: 'fetch'
  });

  pm.sendRequest(csrfRequest, function(err, res) {
    console.log('pm.sendRequest start');
    if (err) {
      console.log(err);
    } else {
      var csrfToken = res.headers.get('x-csrf-token');
      if (csrfToken) {
        console.log('csrfToken fetched:' + csrfToken);
        pm.request.headers.upsert({
          key: 'x-csrf-token',
          value: csrfToken
        });
      } else {
        console.log('No csrf token fetched');
      }
    }
    console.log('pm.sendRequest end');
  });
}

console.log('Pre-request Script from Request end');​

 

The logic here is:

  1. We’re getting the original request and checking if we need to obtain CSRF token or not (we don’t need CSRF token if we’re doing GET or if the token already presented explicitly).
  2. If we’re unlucky enough and we need to obtain CSRF token, we’re cloning the original request. I didn’t find any other way to get the authentication part from the original request into a new request properly and dynamically.
  3. Having the cloned request, we’re immediately changing its method to GET.
  4. Then we’re enriching the URL of the cloned request for performance reason if we need to.
  5. And populating x-csrf-token header of the cloned request with the value “fetch” barging for a token.
  6. As a next step, we’re sending this cloned and modified request providing a call back function. This function will be executed once the request is completed.
  7. In this call back function, we’re checking for any errors, then looking for x-csrf-token header returned to us and if it’s fetched, we’re upserting it (updating if exists, creating if it doesn’t) into the original request.

To use this script, simply copy the code provided and paste it into the tab called Pre-request Script in your Postman’s request. Then click Send to send your POST/PUT/PATCH/DELETE request to C4C oData API.

You can even go further and put this script either into your Folder or Collection in Postman. And then the script will run for any request you’re doing within those folders or collections. You can find out more on the sequence of scripts in Postman documentation.

Assigned Tags

      15 Comments
      You must be Logged on to comment or reply to a post.
      Author's profile photo Cagri Senol
      Cagri Senol

      Great solution! Thank you Andrei, I tested and worked for me. It will be saving a lot time for future work.

      Author's profile photo Andrei Vishnevsky
      Andrei Vishnevsky
      Blog Post Author

      Nice mate! Thank you! Glad it worked. There is more to come 😉

      Author's profile photo Saurabh Kabra
      Saurabh Kabra

      It simply works like charm. Thanks Andrei for the share!

       

      Regards

      Saurabh

      Author's profile photo Andrei Vishnevsky
      Andrei Vishnevsky
      Blog Post Author

      Welcome 🙂

      Author's profile photo Krishna Kishor Kammaje
      Krishna Kishor Kammaje

      Wow! loved this feature.

      Author's profile photo Andrei Vishnevsky
      Andrei Vishnevsky
      Blog Post Author

      Glad you loved it, I use it every day.

      Author's profile photo Kamesh Gonugunta
      Kamesh Gonugunta

      Thank you ! it worked perfect .

      Author's profile photo Vishal Hingole
      Vishal Hingole

      Wonderful (yes) .Thanks

      Author's profile photo Michel Fernandes
      Michel Fernandes

      Great content Andrey, Thanks a lot. 🙂

      Author's profile photo Mahesh Surabattula
      Mahesh Surabattula

      Great stuff. Thanks a lot, Andrei. 🙂

      Author's profile photo Andrei Nicolae Plaiasu
      Andrei Nicolae Plaiasu

      Why re-invent the wheal when somebody has already did it in a perfect manner... saved me a lot of time.. Thanks!

      Author's profile photo YORK LIU
      YORK LIU

      It works when there is no variable in the URL, However, when there is {{HOST}} variable, it could not resolve the variable in the replaced GET request.

      for example : {{C4C_Host}}/sap/c4c/odata/v1/c4codataapi/CustomerOrderCollection/

      Author's profile photo Andrei Vishnevsky
      Andrei Vishnevsky
      Blog Post Author

      Hi York,

      Glad it worked for you. The original intention of the blog post was to provide the simplest solution possible for “real one-click” approach. Setting up variables and including them in the URL – it’s already not one click but many, don’t you agree? ?

      And Postman… Well, Postman doesn’t help in pre-scripts much unfortunately. The script doesn’t resolve the variables by itself. Unless we do something about it. For example, replace the following line from the original script:

      csrfRequest.url = pm.request.url + '?$top=1';

      with a bit extended version:

      csrfRequest.url = pm.variables.replaceIn(pm.request.url) + '?$top=1';

      and you’re good to go even with variables in the URL ?

       

      Author's profile photo Jose Rangel
      Jose Rangel

      Excelent blog! This is very useful and saves a lot of time.

      Author's profile photo RahulDeep Attri
      RahulDeep Attri

      Simple and effective, loved it! Thanks for the code!