Skip to content

Commit

Permalink
Keep Authorization header on subdomain redirects.
Browse files Browse the repository at this point in the history
Closes #173
  • Loading branch information
RubenVerborgh committed Oct 30, 2021
1 parent 2ad9e82 commit 2e1eaf0
Show file tree
Hide file tree
Showing 2 changed files with 63 additions and 2 deletions.
9 changes: 7 additions & 2 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -376,8 +376,8 @@ RedirectableRequest.prototype._processResponse = function (response) {
var redirectUrlParts = url.parse(redirectUrl);
Object.assign(this._options, redirectUrlParts);

// Drop the Authorization header if redirecting to another host
if (redirectUrlParts.host !== currentHost) {
// Drop the Authorization header if redirecting to another domain
if (!(redirectUrlParts.host === currentHost || isSubdomainOf(redirectUrlParts.host, currentHost))) {
removeMatchingHeaders(/^authorization$/i, this._options.headers);
}

Expand Down Expand Up @@ -538,6 +538,11 @@ function abortRequest(request) {
request.abort();
}

function isSubdomainOf(subdomain, domain) {
const dot = subdomain.length - domain.length - 1;
return dot > 0 && subdomain[dot] === "." && subdomain.endsWith(domain);
}

// Exports
module.exports = wrap({ http: http, https: https });
module.exports.wrap = wrap;
56 changes: 56 additions & 0 deletions test/test.js
Original file line number Diff line number Diff line change
Expand Up @@ -1344,6 +1344,62 @@ describe("follow-redirects", function () {
});
});

it("keeps the header when redirected to the same host via header", function () {
app.get("/a", redirectsTo(302, "http:https://localhost:3600/b"));
app.get("/b", function (req, res) {
res.end(JSON.stringify(req.headers));
});

var opts = url.parse("http:https://127.0.0.1:3600/a");
opts.headers = {
host: "localhost:3600",
authorization: "bearer my-token-1234",
};

return server.start(app)
.then(asPromise(function (resolve, reject) {
http.get(opts, resolve).on("error", reject);
}))
.then(asPromise(function (resolve, reject, res) {
res.pipe(concat({ encoding: "string" }, resolve)).on("error", reject);
}))
.then(function (str) {
var body = JSON.parse(str);
assert.equal(body.host, "localhost:3600");
assert.equal(body.authorization, "bearer my-token-1234");
});
});

it("keeps the header when redirected to a subdomain", function () {
app.get("/a", redirectsTo(302, "http:https://sub.localhost:3600/b"));
app.get("/b", function (req, res) {
res.end(JSON.stringify(req.headers));
});

var opts = url.parse("http:https://localhost:3600/a");
opts.headers = {
authorization: "bearer my-token-1234",
};
// Intercept the hostname, as no DNS entry is defined for it
opts.beforeRedirect = function (options) {
assert.equal(options.hostname, "sub.localhost");
options.hostname = "localhost";
};

return server.start(app)
.then(asPromise(function (resolve, reject) {
http.get(opts, resolve).on("error", reject);
}))
.then(asPromise(function (resolve, reject, res) {
res.pipe(concat({ encoding: "string" }, resolve)).on("error", reject);
}))
.then(function (str) {
var body = JSON.parse(str);
assert.equal(body.host, "localhost:3600");
assert.equal(body.authorization, "bearer my-token-1234");
});
});

it("drops the header when redirected to a different host (same hostname and different port)", function () {
app.get("/a", redirectsTo(302, "http:https://localhost:3600/b"));
app.get("/b", function (req, res) {
Expand Down

0 comments on commit 2e1eaf0

Please sign in to comment.