There has been other questions on the subject, but nothing seems working for me.
I have a functional CURL, but I want to translate to JS (with Node).
CURL
curl --user "uername:pass" --digest \
--header "Content-Type: application/json" \
--include \
--request POST "https://cloud.mongodb.com/api/atlas/v1.0/groups/MY_GROUP/clusters/MY_CLUSTER/fts/indexes?pretty=true" \
--data '{
"collectionName": "collname",
"database": "myDB",
"mappings": {
"dynamic": true
},
"name": "default"
}'
Response
HTTP/2 401 www-authenticate: Digest realm="MMS Public API", domain="", nonce="OtwBmcu89QuyVMLW6FP1W/ZjD3preQl0", algorithm=MD5, qop="auth", stale=false content-type: application/json content-length: 106 x-envoy-upstream-service-time: 2 date: Wed, 16 Feb 2022 17:05:37 GMT server: envoy
HTTP/2 200 date: Wed, 16 Feb 2022 17:05:37 GMT strict-transport-security: max-age=31536000; includeSubdomains; referrer-policy: strict-origin-when-cross-origin x-permitted-cross-domain-policies: none x-content-type-options: nosniff x-mongodb-service-version: gitHash=8284a4ea05955cb13c38df5489a3794b9a691d4f; versionString=v20220216 content-type: application/json x-frame-options: DENY content-length: 216 x-envoy-upstream-service-time: 154 server: envoy
I'm not sure why there is a 401 and a 200, but it works. However I get a 401 without the --digest
flag, and none of the solutions below seems to include the digest?
Below are all the ways I tried, which all return 401 "You are not authorized for this resource.":
Fetch
fetch(url,
{
method: 'POST',
headers: {
'Content-Type': 'application/json',
Authorization:
'Basic '
Buffer.from(
'user:pass'
).toString('base64'),
},
body: dataString,
}
)
Same result with
Request
const headers = {
'Content-Type': 'application/json',
};
var options = {
url: url,
method: 'POST',
headers: headers,
body: dataString,
auth: {
user: 'user',
pass: 'pass',
},
};
request(options, (error: any, response: any, body: any) => {
...
});
node-libcurl
const curl = new Curl();
curl.setOpt(Curl.option.HTTPHEADER, [
'Content-Type: application/json',
]);
curl.setOpt(Curl.option.URL, url);
curl.setOpt(Curl.option.POST, true);
curl.setOpt(Curl.option.USERPWD, 'user:pass');
curl.setOpt(Curl.option.POSTFIELDS, dataString);
Even
PHP
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, "...");
curl_setopt($ch, CURLOPT_USERPWD, 'user:pass');
curl_setopt($ch, CURLOPT_HTTPHEADER, ['Content-Type: application/json']);
$result = curl_exec($ch);
curl_close($ch);
Edit for the package request-digest
digestRequest
.requestAsync({
host: url,
path: urlPath,
port: 80,
method: 'POST',
json: true,
headers: {
'Content-Type': 'application/json',
},
body: body,
})
.then(function (response: any) {
console.log(response);
})
.catch(function (error: any) {
console.log(error);
});
Response
Error: Bad request, answer is empty
CodePudding user response:
PHP
You need to specify that it's a digest:
curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_DIGEST);
Node Fetch
This is what I have found here:
fetch(url, {
...
headers: {
'Authorization': 'Basic ' Buffer.from(`${username}:${password}`, 'binary').toString('base64')
}
...
})
Comparing your code with the proposed code above I see that , 'binary'
is missing from yours.
request-digest
There is a request-digest package that may help you. Examples (taken from the link shared in this paragraph):
Callback
var digestRequest = require('request-digest')('username', 'password');
digestRequest.request({
host: 'http://test.com',
path: '/api/v1/test.json',
port: 80,
method: 'GET',
headers: {
'Custom-Header': 'OneValue',
'Other-Custom-Header': 'OtherValue'
}
}, function (error, response, body) {
if (error) {
throw error;
}
console.log(body);
});
Promise-only
var digestRequest = require('request-digest')('username', 'password');
digestRequest.requestAsync({
host: 'http://test.com',
path: '/api/v1/test.json',
port: 80,
method: 'GET',
excludePort: false,
headers: {
'Custom-Header': 'OneValue',
'Other-Custom-Header': 'OtherValue'
}
})
.then(function (response) {
console.log(response.body);
})
.catch(function (error) {
console.log(error.statusCode);
console.log(error.body);
});