Missing 'accept-language' header in Express - node.js

I would like to use value of accept-language header for detecting language in node.js server created with using Express.
However when I try to get with headers:
console.dir(req.headers)
there is no accept-language field, other headers are present. But I can see 'Accept-Language' in chrome tab.
I am making request with JS fetch with this configuration:
fetch('/path/somepath', {
method: 'POST',
credentials: 'include',
headers: {
'Content-Type': 'application/json;charset=utf-8'
},
body: JSON.stringify(input)
})
What could be possible reasons of this behaviour and is something what I can do? I do not want to set this header explicitly in fetch because I would like it to create automatically on basis of browser settings.

Related

Secured way to communicate between servers

We are passing secret keys to authenticate the GET requests between https enabled websites. Which of the following ways are more secured:
GET /auth?secret=8727n2i752gns982jsn'
Only 2 servers know that secret keys.
Or should we set headers as follows:
request({
url: '/auth',
headers: {
'secretKey': 's87ehwdiw8y3dhj'
}
});
Which method is more secured and why?
Ideally sending secret key isn't a good option. But if there is utmost need I would suggest you to send the key in the headers like:
request({
url: '/auth',
headers: {
'secretKey': 's87ehwdiw8y3dhj'
}
});
If you give a "secret key" to a browser, it's not secret anymore. Javascript in the browser is just too open to really keep a key secret.
As it is less visible, yet anyone can sniff it as it's just javascript.
Here are few links to enlighten you more:
1
2
3
4
request({
url: '/auth',
headers: {
'Authorization': 'Bearer s87ehwdiw8y3dhj'
}
});
This is a standardized way of passing tokens through header. The security part is really more about your token creation.
'Bearer' is the type of Authorization you are using. It could be 'Basic', etc
ie
'Authorization': 'Basic s87ehwdiw8y3dhj'

Intercept sending request to change a header with request library

I am using the infamous request library to send requests.
One of those requests requires me to send the header multipart/mixed; boundary={myboundary}.
Request is using the form-data library for such requests but it does not set the Content-Type header properly. Therefore I would need to set it like this:
let req = request.post({url: "https://..."}, formData: formData)
req.setHeader('Content-Type', `multipart/mixed; boundary=${req.form().getBoundary()}`)
Sadly I can't add/alter any headers after firing the request. Therefore I want to know whether there is a way to intercept the sending so I can change the header?
You will need to use the multipart option instead of formData to use other, arbitrary multipart/* content types. Each object in the multipart array contains the headers to send in that part. The one exception is the body property which is used as the actual body of that part.
request.post({
url: 'https://...',
multipart: [
{ 'X-Foo-Header': 'bar', body: 'baz' },
// ...
],
headers: { 'Content-Type': 'multipart/mixed' }
});
The boundary should be automatically appended for an existing, explicit Content-Type header. This request test explicitly tests for this behavior.

Error with signature when creating an outbound shipment on Amazon MWS API

I'm trying to create an outbound fulfillment (CreateFulfillmentOrder) on the Amazon MWS API. I'm using the node.js package mws-api to make the request, which I have modified myself since it didn't support this operation correctly. In any case, this is the exact request that I'm sending to the API (with sensitive information changed):
{
uri: 'https://mws.amazonservices.co.uk/FulfillmentOutboundShipment/2010-10-01',
method: 'POST',
headers:
{ Host: 'mws.amazonservices.co.uk',
'User-Agent': 'mws-api/0.1.0 (Language=JavaScript)',
'content-type': 'application/x-www-form-urlencoded',
'content-length': 1095 },
body: 'SellerFulfillmentOrderId=403-9883411-3564317&ShippingSpeedCategory=Standard&DisplayableOrderId=403-9883411-3564317&DisplayableOrderDateTime=2013-12-29&DisplayableOrderComment=Order&NotificationEmailList.member.1=3yv4at7rtl3blsy%40marketplace.amazon.co.uk&DestinationAddress.Name=Amazon%20Taro&DestinationAddress.Line1=COMPANY%NAME&DestinationAddress.City=GORING&DestinationAddress.StateOrProvinceCode=Oxon&DestinationAddress.PostalCode=RG8%209AQ&DestinationAddress.CountryCode=GB&DestinationAddress.PhoneNumber=01575375219&Items.member.1.DisplayableComment=item&Items.member.1.GiftMessage=gift&Items.member.1.PerUnitDeclaredValue.Value=4.29&Items.member.1.PerUnitDeclaredValue.CurrencyCode=GBP&Items.member.1.Quantity=1&Items.member.1.SellerFulfillmentOrderItemId=CW0298&Items.member.1.SellerSKU=CW0298&Action=CreateFulfillmentOrder&Version=2010-10-01&Timestamp=2017-04-12T14%3A39%3A22.707Z&AWSAccessKeyId=LYIAJ83AORVSI6WLBTQA&SellerId=7RVB74LQNDFDB1&SignatureMethod=HmacSHA256&SignatureVersion=2&Signature=nlB5UTDUXexkurlsc7e%2F4tqLO8vcMRy4X%6Oa0rPIapZN8%3D' }
But all I'm getting in response is this error:
The request signature we calculated does not match the signature you provided. Check your AWS Secret Access Key and signing method. Consult the service documentation for details.
I don't there's any problem with the signature, it has worked correctly while doing other operations. I think that's just the error Amazon gives you when something's wrong on the request, but I cannot find the problem. Does anyone know what could be the problem?
Thanks.
You need to use Amazon Host mws.amazonaws.com.
Ex:
{
uri: 'https://mws.amazonaws.com/FulfillmentOutboundShipment/2010-10-01',
method: 'POST',
headers:
{ Host: 'mws.amazonaws.com',
'User-Agent': 'mws-api/0.1.0 (Language=JavaScript)',
'content-type': 'application/x-www-form-urlencoded',
'content-length': 1095
},
body:'SellerFulfillmentOrderId=403-9883411-3564317&ShippingSpeedCategory=Standard&DisplayableOrderId=403-9883411-3564317&DisplayableOrderDateTime=2013-12-29&DisplayableOrderComment=Order&NotificationEmailList.member.1=3yv4at7rtl3blsy%40marketplace.amazon.co.uk&DestinationAddress.Name=Amazon%20Taro&DestinationAddress.Line1=COMPANY%NAME&DestinationAddress.City=GORING&DestinationAddress.StateOrProvinceCode=Oxon&DestinationAddress.PostalCode=RG8%209AQ&DestinationAddress.CountryCode=GB&DestinationAddress.PhoneNumber=01575375219&Items.member.1.DisplayableComment=item&Items.member.1.GiftMessage=gift&Items.member.1.PerUnitDeclaredValue.Value=4.29&Items.member.1.PerUnitDeclaredValue.CurrencyCode=GBP&Items.member.1.Quantity=1&Items.member.1.SellerFulfillmentOrderItemId=CW0298&Items.member.1.SellerSKU=CW0298&Action=CreateFulfillmentOrder&Version=2010-10-01&Timestamp=2017-04-12T14%3A39%3A22.707Z&AWSAccessKeyId=LYIAJ83AORVSI6WLBTQA&SellerId=7RVB74LQNDFDB1&SignatureMethod=HmacSHA256&SignatureVersion=2&Signature=nlB5UTDUXexkurlsc7e%2F4tqLO8vcMRy4X%6Oa0rPIapZN8%3D'
}
This may help you.

Docusign console view request is giving "errorCode": "INVALID_CONTENT_TYPE"

I have following request sent to docusign to get the console view of the document, but I'm getting "INVALID_CONTENT_TYPE"
All informations below are arbitrary because of privacy concern. I want to know if the request is correct.
{ method: 'POST',
uri: 'https://demo.docusign.net/restapi/v2/accounts/+' accountId '+/views/console',
body: '{"envelopeId":"a40b28fa-a89f-49e0-af03-2342334234"}',
headers:
{ 'X-DocuSign-Authentication': '{"Username":username,"Password":password,"IntegratorKey":"INTKEY-sjdfhf876-1cf4-4776-aac1-786767676"}',
'Content-Type': 'application/json',
'content-length': '58' } }
I tried to repro this and my request was successful. The only difference between my invocation and yours was the quotes around 'application/json'. Remove the quotes.

Getting 401 uploading file into a table with a service account

I am using nodejs and the REST API to interact with bigquery. I am using the google-oauth-jwt module for JWT signing.
I granted a service account write permission. So far I can list projects, list datasets, create a table and delete a table. But when it comes to upload a file via multipart POST, I ran into two problems:
gzipped json file doesn't work, I get an error saying "end boundary missing"
when I use uncompressed json file, I get a 401 unauthorized error
I don't think this is related to my machine's time being out of sync since other REST api calls worked as expected.
var url = 'https://www.googleapis.com/upload/bigquery/v2/projects/' + projectId + '/jobs';
var request = googleOauthJWT.requestWithJWT();
var jobResource = {
jobReference: {
projectId: projectId,
jobId: jobId
},
configuration: {
load: {
sourceFormat: 'NEWLINE_DELIMITED_JSON',
destinationTable: {
projectId: projectId,
datasetId: datasetId,
tableId: tableId
},
createDisposition: '',
writeDisposition: ''
}
}
};
request(
{
url: url,
method: 'POST',
jwt: jwtParams,
headers: {
'Content-Type': 'multipart/related'
},
qs: {
uploadType: 'multipart'
},
multipart: [
{
'Content-Type':'application/json; charset=UTF-8',
body: JSON.stringify(jobResource)
},
{
'Content-Type':'application/octet-stream',
body: fileBuffer.toString()
}
]
},
function(err, response, body) {
console.log(JSON.parse(body).selfLink);
}
);
Can anyone shine some light on this?
P.S. the documentation on bigquery REST api is not up to date on many things, wish the google guys can keep it updated
Update 1:
Here is the full HTTP request:
POST /upload/bigquery/v2/projects/239525534299/jobs?uploadType=multipart HTTP/1.1
content-type: multipart/related; boundary=71e00bd1-1c17-4892-8784-2facc6998699
authorization: Bearer ya29.AHES6ZRYyfSUpQz7xt-xwEgUfelmCvwi0RL3ztHDwC4vnBI
host: www.googleapis.com
content-length: 876
Connection: keep-alive
--71e00bd1-1c17-4892-8784-2facc6998699
Content-Type: application/json
{"jobReference":{"projectId":"239525534299","jobId":"test-upload-2013-08-07_2300"},"configuration":{"load":{"sourceFormat":"NEWLINE_DELIMITED_JSON","destinationTable":{"projectId":"239525534299","datasetId":"performance","tableId":"test_table"},"createDisposition":"CREATE_NEVER","writeDisposition":"WRITE_APPEND"}}}
--71e00bd1-1c17-4892-8784-2facc6998699
Content-Type: application/octet-stream
{"practiceId":2,"fanCount":5,"mvp":"Hello"}
{"practiceId":3,"fanCount":33,"mvp":"Hello"}
{"practiceId":4,"fanCount":71,"mvp":"Hello"}
{"practiceId":5,"fanCount":93,"mvp":"Hello"}
{"practiceId":6,"fanCount":92,"mvp":"Hello"}
{"practiceId":7,"fanCount":74,"mvp":"Hello"}
{"practiceId":8,"fanCount":100,"mvp":"Hello"}
{"practiceId":9,"fanCount":27,"mvp":"Hello"}
--71e00bd1-1c17-4892-8784-2facc6998699--
You are most likely sending duplicate content-type headers to the Google API.
I don't have the capability to effortlessly make a request to Google BigQuery to test, but I'd start with removing the headers property of your options object to request().
Remove this:
headers: {
'Content-Type': 'multipart/related'
},
The Node.js request module automatically detects that you have passed in a multipart array, and it adds the appropriate content-type header. If you provide your own content-type header, you most likely end up with a "duplicate" one, which does not contain the multipart boundary.
If you modify your code slightly to print out the actual headers sent:
var req = request({...}, function(..) {...});
console.log(req.headers);
You should see something like this for your original code above (I'm using the Node REPL):
> req.headers
{ 'Content-Type': 'multipart/related',
'content-type': 'multipart/related; boundary=af5ed508-5655-48e4-b43c-ae5be91b5ae9',
'content-length': 271 }
And the following if you remove the explicit headers option:
> req.headers
{ 'content-type': 'multipart/related; boundary=49d2371f-1baf-4526-b140-0d4d3f80bb75',
'content-length': 271 }
Some servers don't deal well with multiple headers having the same name. Hopefully this solves the end boundary missing error from the API!
I figured this out myself. This is one of those silly mistakes that would have you stuck for the whole day and at the end when you found the solution you would really knock on your own head.
I got the 401 by typing the selfLink URL in the browser. Of course it's not authorized.

Resources