When I use the username/password with got, It seems that the combo 'username:password' is encoded with encodeURI() before to be encode in base64 for the basic auth. This first encoding is not necessary due to the base64 encoding and brings problems. So when the encodeURI() change a value like '@' to '%40', the basic authentification doesn't work.
Just encode the combo 'username:password' with base64 encoding.
const got = require('got');
(async () => {
const response = await got.head("http://example.com/", {username: "user@", password: "password@"});
console.info("Response:", response.client._httpMessage._header);
}) ();
We see that the Authorization header is invalid
It's a Node.js issue:
const https = require('https');
const getStream = require('get-stream');
const url = new URL('https://httpbin.org/anything');
url.username = 'user@';
url.password = 'password';
https.get(url, async response => {
const body = await getStream(response);
console.log(JSON.parse(body));
});
I'm not sure whether it's a bug or valid behavior...
Reference: https://tools.ietf.org/html/rfc2617 (haven't looked at it yet)
Took a quick look and found this:
user-pass = userid ":" password
userid = *<TEXT excluding ":">
password = *TEXT
also nodejs/node#31450
The both issues are still open in Nodejs.
I did this workaround on my side until Nodejs fixes the issue:
const headers = {
"Authorization": "Basic " + Buffer.from(`user@:password@`).toString("base64")
};
await got(encodeURI("http://example.com/"), { headers });
I built the Authorization header instead of filling username and password members of the options objects.
If Nodejs only fixes it on the new version, maybe Got can fix the issue on their side to avoid the bug on old Nodejs versions.
maybe Got can fix the issue on their side
We could implement a workaround, but it's not the proper solution. The bug is not a big one, so I'd rather wait until it's fixed on Node.js side. But if you really need this badly, you can send a PR :)
@szmarczak Let the library encode it properly, internally. I feel this is a major issue since the library has the options.username and options.password option.
Most helpful comment
also nodejs/node#31450
The both issues are still open in Nodejs.
I did this workaround on my side until Nodejs fixes the issue:
I built the Authorization header instead of filling username and password members of the options objects.
If Nodejs only fixes it on the new version, maybe Got can fix the issue on their side to avoid the bug on old Nodejs versions.