I can make a GET request with an Authorization header from curl
but not from request
or https
in Node.js. The server returns status 200 with curl but 500 with request
or https
. How might the call from request
or https
be different from curl
? How might the server be reading them differently?
The following cURL succeeds from command line:
curl -H "Authorization: Bearer abc123def456" https://api.domain.com/path/to/resource
But the same request fails with request.js in Node
var options = {
type: 'get',
url: "https://api.domain.com/path/to/resource",
headers: {
"Authorization": " Bearer abc123def456"
}
}
request(options, function (err, response, body) {
assert.equal(response.statusCode, 200) ; // 500 internal error
})
The following also fails with request.js using the auth
option:
var options = {
type: 'get',
url: "https://api.domain.com/path/to/resource",
auth: {
"bearer": "abc123def456"
}
}
request(options, function (err, response, body) {
assert.equal(response.statusCode, 200) ; // 500 internal error
})
It also fails when using https
without request.js
:
var options = {
host: 'api.domain.com',
port: 443,
path: '/path/to/info',
method: 'GET',
headers: {
"Authorization": " Bearer abc123def456"
}
}
var req = https.request(options, function (res) {
res.setEncoding('utf8');
res.on('end', function () {
assert.equal(res.statusCode, 200) // 500 internal error
})
});
req.on('error', function (e) {
console.log('problem with request: ' + e.message);
});
req.end();
But the curl requests succeeds if shelled out from Node:
exec("curl -H "Authorization: Bearer abc123def456" https://api.domain.com/path/to/resource", function (error, stdout, stderr) {
var obj = JSON.parse(stdout) // successfully retrieved and parsed
});
request-debug
gives the following info:
{ request:
{ debugId: 1,
uri: 'https://api.domain.com/path/to/resource',
method: 'GET',
headers:
{ host: 'api.domain.com',
authorization: 'Bearer abc123def456' } } }
500 internal error generally means there is an error at the server side . So, ideally, you should be taking a look at the server logs.
However, if you don't have access to those logs, look at the difference between the requests sent by each one of the options you tried:
Module: Request (with manually specified auth header):
GET /path/to/resource HTTP/1.1
Authorization: Bearer abc123def456
host: api.domain.com
Module: Request (with explicitly specified auth header):
GET /path/to/resource HTTP/1.1
host: api.domain.com
authorization: Bearer abc123def456
Module: HTTP (with manually specified auth header):
GET /path/to/info HTTP/1.1
Authorization: Bearer abc123def456
Host: api.domain.com
Curl:
GET /path/to/resource HTTP/1.1
Host: api.domain.com
User-Agent: curl/7.51.0
Accept: */*
Authorization: Bearer abc123def456
It is quite evident that the rest of the modules do not send the HTTP headers 'User-Agent' and 'Accept'. So, it could be the case that the app running on the server is trying to parse at least one of this and failing.