Error 401 - Groups (Working in Postman but neither in Vue Js neither in Php)

Hello,
I'm using a demo access to the worldcheck api.
I have my key and my secret key.
Postman is working. I have access and results.
I've 401 Unauthorised Access problems when I try to implement the access through frontend (vuejs using either fetch or axios) or through backend (php).
For vue js, I adapted the nodejs example. And the code is really similar (javascript in both cases).
I also compared the authorization header i'm getting in postman and in vue js and they are identical.
Here is an example :
- Vue JS -
Date: Thu, 24 Oct 2019 14:39:52 GMT
Authorization: Signature keyId="******************************",algorithm="hmac-sha256",headers="(request-target) host date",signature="bhT39ij/iE1851ZH402zYahPmAEZtkK/riL/CQvvM4w="
- PostMan
Date: Thu, 24 Oct 2019 14:39:52 GMT
Authorization: Signature keyId="***************************",algorithm="hmac-sha256",headers="(request-target) host date",signature="bhT39ij/iE1851ZH402zYahPmAEZtkK/riL/CQvvM4w="
I would welcome any support or hint of explorations.
Thanks in advance,
Best regards,
Emmanuel
Here is the vue js code :
<template>
<div>
WORLDCHECK
</div>
</template>
<script>
import CryptoJS from 'crypto-js'
export default {
mounted () {
this.initialize()
},
methods: {
generateAuthHeader(dataToSign){
var hash = CryptoJS.HmacSHA256(dataToSign,process.env.worldcheck.WC1_APISECRETKEY);
return hash.toString(CryptoJS.enc.Base64);
},
initialize () {
var gatewayhost = process.env.worldcheck.WC1_GATEWAYHOST;
var gatewayurl = process.env.worldcheck.WC1_GATEWAYURL;
var apikey = process.env.worldcheck.WC1_APIKEY;
var apisecretkey = process.env.worldcheck.WC1_APISECRETKEY;
var date = new Date().toGMTString();
console.log("date", date);
var datas = "";
var dataToSign = "(request-target): get " + gatewayurl + "groups"
+ "\n" + "host: " + gatewayhost
+ "\n" + "date: " + date
// + "\n" + "content-type: " + "application/json"
// + "\n" + "content-length: " + datas.length
// + "\n" + datas
;
console.log("dataToSign", dataToSign);
var hmac = this.generateAuthHeader(dataToSign);
console.log("hmac", hmac);
//var authorisation = 'Signature keyId="' + apikey + '",algorithm="hmac-sha256",headers="(request-target) host date content-type content-length",signature="' + hmac + '"';
var authorisation = 'Signature keyId="' + apikey + '",algorithm="hmac-sha256",headers="(request-target) host date",signature="' + hmac + '"';
console.log("authorisation", authorisation);
// GET headers is just date & authorization, no body
var headers = {"Date": date, "Authorization": authorisation};
//var headers = {"currentdate": date, "authorization": authorisation};
console.log("headers", headers);
var url = 'https://'+gatewayhost+ gatewayurl + 'groups';
console.log("url", url);
fetch(url, {method: 'GET', headers: new Headers(headers)})
.then(response => {
console.log("THIS SHOULD HAVE DATA", response.data);
this.result = response.data
})
.catch(error => {
console.log('fetch',error)
});
},
},
layout:"layout_steps"
}
</script>
<style>
</style>
Here is the php code :
<?php
require_once('./apiinfo.php');
header("Content-Type: application/json; charset=utf-8");
header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Methods: GET, POST, OPTIONS, PUT, PATCH, DELETE');
header('Access-Control-Allow-Headers: X-Requested-With, content-type, Authorization');
$gatewayhost = WC1_GATEWAYHOST;
$gatewayurl = WC1_GATEWAYURL;
$apikey = WC1_APIKEY;
$apisecretkey = WC1_APISECRETKEY;
$dateTime = new DateTime('now GMT');
$date = $dateTime->format('D, d M Y H:i:s') . ' GMT';
$dataToSign = "(request-target): get " . $gatewayurl . "groups"."\n" . "host: " . $gatewayhost . "\n" . "date: " . $date;
$hmac_brut = hash_hmac('sha256', $dataToSign, $apisecretkey);
$hmac = base64_encode($hmac_brut);
$authorisation = "Signature keyId=\"" . $apikey . "\",algorithm=\"hmac-sha256\",headers=\"(request-target) host date\",signature=\"" . $hmac . "\"";
//$headers = {'Date': $date, 'Authorization': $authorisation};
$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_URL => "https://rms-world-check-one-api-pilot.thomsonreuters.com/v1/groups",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => array(
"Accept: */*",
"Accept-Encoding: gzip, deflate",
"Authorization: ".$authorisation,
"Cache-Control: no-cache",
"Connection: keep-alive",
"Date: ".$date,
"Host: rms-world-check-one-api-pilot.thomsonreuters.com",
"cache-control: no-cache"
),
));
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
print(json_encode("cURL Error #:" . $err));
} else {
print( $response ? $response : json_encode("EMPTY RESPONSE"));
}
Best Answer
-
Hi,
on the PHP code front, I see that when you are declaring the hmac function you are missing a parameter "raw_output".
"$hmac_brut = hash_hmac('sha256', $dataToSign, $apisecretkey); "
Can you please go through the below link for more insights
https://www.php.net/manual/en/function.hash-hmac.php
And about the node.js request, can you please share the complete request and response headers so that we can investigate it further?
Regards,
Mehran Khan
0
Answers
-
Hi,
I'm looking into the details that you have provided, please allow me some time to get back with my analyses.
Regards
0 -
Hi Mehran,
Thank you very much for your hint in php. It helped to solve the problem. I will get it through backend.
In case you have any clue for the front end part (why does it not work), I added any the detailed information below.
Anyway I can now go on, and many thanks.
Best regards,
Emmanuel
- Vue JS
I'm not using node js but vue js, a front-end framework in javascript with axios or fetch (<=> ajax) to access data.
In this configuration, I compared the hmac between postman and vuejs and it's the same.
I managed to send the request at the same second so it's easy to compare.
--> Here is the node js native code postman give to me :
var http = require("https");
var options = {
"method": "GET",
"hostname": [
"rms-world-check-one-api-pilot",
"thomsonreuters",
"com"
],
"path": [
"v1",
"groups"
],
"headers": {
"Date": "Mon, 28 Oct 2019 09:36:06 GMT",
"Authorization": "Signature keyId=\"a13d27fe-0a3e-4d82-85b7-5e07fd71576a\",algorithm=\"hmac-sha256\",headers=\"(request-target) host date\",signature=\"tvhM/ZzibTm7qN+Fsd/75JMjah41ZIhiYa7tGDW4yok=\"",
"User-Agent": "PostmanRuntime/7.19.0",
"Accept": "*/*",
"Cache-Control": "no-cache",
"Postman-Token": "ea60eb62-12f2-4b56-8a69-5fc1f0ee84ad,94042e62-709a-4f68-b731-f223b9882b25",
"Host": "rms-world-check-one-api-pilot.thomsonreuters.com",
"Accept-Encoding": "gzip, deflate",
"Connection": "keep-alive",
"cache-control": "no-cache"
}
};
var req = http.request(options, function (res) {
var chunks = [];
res.on("data", function (chunk) {
chunks.push(chunk);
});
res.on("end", function () {
var body = Buffer.concat(chunks);
console.log(body.toString());
});
});
req.end();
--> Here is the httt request postman give to me :
GET /v1/groups HTTP/1.1
Host: rms-world-check-one-api-pilot.thomsonreuters.com
Date: Mon, 28 Oct 2019 09:36:06 GMT
Authorization: Signature keyId="a13d27fe-0a3e-4d82-85b7-5e07fd71576a",algorithm="hmac-sha256",headers="(request-target) host date",signature="tvhM/ZzibTm7qN+Fsd/75JMjah41ZIhiYa7tGDW4yok="
User-Agent: PostmanRuntime/7.19.0
Accept: */*
Cache-Control: no-cache
Postman-Token: ea60eb62-12f2-4b56-8a69-5fc1f0ee84ad,d000bbc6-202d-499d-917b-6fd446de4608
Host: rms-world-check-one-api-pilot.thomsonreuters.com
Accept-Encoding: gzip, deflate
Connection: keep-alive
cache-control: no-cache
--> Here is the vue js parameters :
date: Mon, 28 Oct 2019 09:36:06 GMT
authorization: Signature keyId="a13d27fe-0a3e-4d82-85b7-5e07fd71576a",algorithm="hmac-sha256",headers="(request-target) host date",signature="tvhM/ZzibTm7qN+Fsd/75JMjah41ZIhiYa7tGDW4yok="
- settings
var settings = {
"async": true,
"crossDomain": true,
"url": "https://rms-world-check-one-api-pilot.thomsonreuters.com/v1/groups",
"method": "GET",
"headers": {
"Date": date,
"Authorization": authorisation,
"User-Agent": "PostmanRuntime/7.18.0",
"Accept": "*/*",
"Cache-Control": "no-cache",
"Postman-Token": "1785229a-a598-46dd-b2e5-5f8b0c2d1f04,c31fcdb7-8767-4175-a276-5170bd6321ff",
"Host": "rms-world-check-one-api-pilot.thomsonreuters.com",
"Accept-Encoding": "gzip, deflate",
"Connection": "keep-alive",
"cache-control": "no-cache"
}
- Header Response as given by Firefox
HTTP/1.1 401 Unauthorized
X-Application-Context: application
Authorization: WWW-Authenticate: Signature realm="World-Check One API",algorithm="hmac-sha256",headers="(request-target) host date content-type content-length
Allow: GET, HEAD, POST, PUT, DELETE, TRACE, OPTIONS, PATCH
Transfer-Encoding: chunked
Date: Mon, 28 Oct 2019 09:36:06 GMT
Server: ""
- Header Request as given by Firefox
Host: rms-world-check-one-api-pilot.thomsonreuters.com
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:70.0) Gecko/20100101 Firefox/70.0
Accept: */*
Accept-Language: fr,fr-FR;q=0.8,en-US;q=0.5,en;q=0.3
Accept-Encoding: gzip, deflate, br
Access-Control-Request-Method: GET
Access-Control-Request-Headers: authorization,cache-control,postman-token,user-agent
Referer: http://localhost:3000/worldcheck
Origin: http://localhost:3000
DNT: 1
Connection: keep-alive
Pragma: no-cache
Cache-Control: no-cache0
Categories
- All Categories
- 3 Polls
- 6 AHS
- 36 Alpha
- 166 App Studio
- 6 Block Chain
- 4 Bot Platform
- 18 Connected Risk APIs
- 47 Data Fusion
- 34 Data Model Discovery
- 684 Datastream
- 1.4K DSS
- 614 Eikon COM
- 5.2K Eikon Data APIs
- 10 Electronic Trading
- Generic FIX
- 7 Local Bank Node API
- 3 Trading API
- 2.9K Elektron
- 1.4K EMA
- 248 ETA
- 552 WebSocket API
- 37 FX Venues
- 14 FX Market Data
- 1 FX Post Trade
- 1 FX Trading - Matching
- 12 FX Trading – RFQ Maker
- 5 Intelligent Tagging
- 2 Legal One
- 23 Messenger Bot
- 3 Messenger Side by Side
- 9 ONESOURCE
- 7 Indirect Tax
- 60 Open Calais
- 275 Open PermID
- 44 Entity Search
- 2 Org ID
- 1 PAM
- PAM - Logging
- 6 Product Insight
- Project Tracking
- ProView
- ProView Internal
- 22 RDMS
- 1.9K Refinitiv Data Platform
- 640 Refinitiv Data Platform Libraries
- 4 LSEG Due Diligence
- LSEG Due Diligence Portal API
- 4 Refinitiv Due Dilligence Centre
- Rose's Space
- 1.2K Screening
- 18 Qual-ID API
- 13 Screening Deployed
- 23 Screening Online
- 12 World-Check Customer Risk Screener
- 1K World-Check One
- 46 World-Check One Zero Footprint
- 45 Side by Side Integration API
- 2 Test Space
- 3 Thomson One Smart
- 10 TR Knowledge Graph
- 151 Transactions
- 143 REDI API
- 1.8K TREP APIs
- 4 CAT
- 26 DACS Station
- 121 Open DACS
- 1.1K RFA
- 104 UPA
- 191 TREP Infrastructure
- 228 TRKD
- 915 TRTH
- 5 Velocity Analytics
- 9 Wealth Management Web Services
- 90 Workspace SDK
- 11 Element Framework
- 5 Grid
- 18 World-Check Data File
- 1 Yield Book Analytics
- 46 中文论坛