title: Postman - access full request body (to calculate hash) in pre-request script
body: <p>I'm trying to recreate C# DelegatingHandler inside PostMan.<br/>
  I've created pre-request script that calculates auth header value.</p>
  
  <p>Currently my script looks like this:</p>
  
  <pre><code>function S4() {
      return (((1+Math.random())*0x10000)|0).toString(16).substring(1); 
  }
  
  function GetNonce() {
      return (S4() + S4() + S4()+ S4() + S4() + S4() + S4()+ S4()).toLowerCase();
  }
  
  function GetTimeStamp() {
      var d = new Date();
      return Math.round(d.getTime() / 1000);
  }
  
  function getAuthHeader(httpMethod, requestUrl, requestBody) {
      var CLIENT_KEY = postman.getEnvironmentVariable('hmac_user');
      var SECRET_KEY = postman.getEnvironmentVariable('hmac_key');
      var AUTH_TYPE = 'HMAC';
  
      requestUrl = requestUrl.replace(/{{(\w*)}}/g,function(str,key) {return environment[key]});
      requestUrl = requestUrl.toLowerCase();
      var requestTimeStamp = GetTimeStamp();
      var nonce = GetNonce();
      var bodyHash="";
  
      if (httpMethod == 'GET' || !requestBody) {
          requestBody = ''; 
      } else {
          var md5 = CryptoJS.MD5(requestBody);
          bodyHash = CryptoJS.enc.Base64.stringify(md5);
      }  
  
      var signatureRawData = [CLIENT_KEY, requestUrl, httpMethod, requestTimeStamp, nonce, bodyHash].join("");
  
      var key = CryptoJS.enc.Base64.parse(SECRET_KEY);
      var hash = CryptoJS.HmacSHA512(signatureRawData, key);
      var hashInBase64 = CryptoJS.enc.Base64.stringify(hash);
  
      var header = [CLIENT_KEY, hashInBase64, nonce, requestTimeStamp].join(":");
  
      return AUTH_TYPE+" "+header;
  }
  
  postman.setEnvironmentVariable('hmacAuthHeader', getAuthHeader(request.method, request.url, request.data));
  </code></pre>
  
  <p>This works perfect for GET requests that don't have any body. However when I send <code>x-www-form-urlencoded</code> request I get unauthorized response (401), because of body hash differences inside C# and Postman.</p>
  
  <p>Inside Postman <code>request.data</code> is a JSON object, but when I investigate request in Fiddler I see it is send as string (see below screenshot)
  <a href="https://i.stack.imgur.com/S8d7k.png" rel="noreferrer"><img src="https://i.stack.imgur.com/S8d7k.png" alt="enter image description here"></a></p>
  
  <p>Same thing happens when I send <code>form-data</code>. Inside Postman I've added 3 fields, one with string value, two with files. In Fiddler I can see full request, but inside Postman I can't access those files (see below screenshot) 
  <a href="https://i.stack.imgur.com/d1Pig.png" rel="noreferrer"><img src="https://i.stack.imgur.com/d1Pig.png" alt="enter image description here"></a></p>
  
  <p>I'm trying to access full request body, because I need to calculate hash out of it.</p>
  
  <p>I have working code in C#, not I want to recreate same requests with Postman.</p>
  
  <p>My question is:<br><strong>How can I access full request body in pre-request script?</strong></p>
  
  <p>I use this code in C# and it works fine:</p>
  
  <pre><code>internal class HmacClientHandler : DelegatingHandler
  {
      private readonly string _applicationId;
      private readonly string _applicationKey;
  
      public HmacClientHandler(string appId, string appKey)
      {
          _applicationId = appId;
          _applicationKey = appKey;
      }
  
      protected override async Task&lt;HttpResponseMessage&gt;SendAsync(HttpRequestMessage request,CancellationToken cancellationToken)
      {
          HttpResponseMessage response = null;
          string url = Uri.EscapeUriString(request.RequestUri.ToString().ToLowerInvariant());
          string methodName = request.Method.Method;
  
          DateTime epochStart = new DateTime(1970, 01, 01, 0, 0, 0, 0, DateTimeKind.Utc);
          TimeSpan timeSpan = DateTime.UtcNow - epochStart;
          string requestTimeStamp = Convert.ToUInt64(timeSpan.TotalSeconds).ToString();
          string nonce = Guid.NewGuid().ToString("N");
  
          string contentBase64String = string.Empty;
  
          if (request.Content != null)
          {
              byte[] content = await request.Content.ReadAsByteArrayAsync();
              MD5 md5 = MD5.Create();
              byte[] hash = md5.ComputeHash(content);
              contentBase64String = Convert.ToBase64String(hash);
          }
  
          string authenticationKeyString = string.Format("{0}{1}{2}{3}{4}{5}", _applicationId, url, methodName, requestTimeStamp, nonce, contentBase64String);
          var secretKeyBase64ByteArray = Convert.FromBase64String(_applicationKey);
  
          using (HMACSHA512 hmac = new HMACSHA512(secretKeyBase64ByteArray))
          {
              byte[] authenticationKeyBytes = Encoding.UTF8.GetBytes(authenticationKeyString);
              byte[] authenticationHash = hmac.ComputeHash(authenticationKeyBytes);
              string hashedBase64String = Convert.ToBase64String(authenticationHash);
              request.Headers.Authorization = new AuthenticationHeaderValue("HMAC", string.Format("{0}:{1}:{2}:{3}", _applicationId, hashedBase64String, nonce, requestTimeStamp));
          }
  
          response = await base.SendAsync(request, cancellationToken);
          return response;
      }
  }
  </code></pre>