http-party / node-http-proxy

A full-featured http proxy for node.js
https://github.com/http-party/node-http-proxy
Other
13.89k stars 1.97k forks source link

Basic Auth not set in forwarded request if already supplied in initial request #1088

Open garysmith-github opened 7 years ago

garysmith-github commented 7 years ago

I have a service that is proxying requests to RESTHeart.

My service requires BasicAuth criteria#1 and RESTHeart requires BasicAuth criteria#2 ('admin:changeit'). In my service I amend the URL of the target, set the auth and make the proxy.web() call with new those options:

`var target = util.format("http://%s:%d%s", RESTHEART_HOST, RESTHEART_PORT, path); var options = { target: target, ignorePath: true, auth: 'admin:changeit', method: clientRequest.method };

proxy.web(clientRequest, clientResponse, options, function(err){
    /// stuff here
});`

This gives a 401. On inspection this was due to the criteria#1 being passed in the proxied request. I also tried embedding auth in the target, viz:

var target = util.format("http://admin:changeit@%s:%d%s", RESTHEART_HOST, RESTHEART_PORT, path);

But likewise, this returns a 401.

Eventually I set the original auth in the client request to null which then forced http-proxy to work as expected, by inserting the following line above the var options:

clientRequest.headers.authorization = '';

Comments?

rgolea commented 7 years ago

I'm having a similar issue here. I'm having this module rerouting all my connections from my local server to my api. The proxy redirects properly the cookies but it doesn't redirect properly when my client request has another header:

//server
app.use(dependencies.apiPath, (req, res) => {
   proxy.web(req, res, {
      target: apiRoot
   });
});
//client
config.headers.authorization = `Bearer ${token}`;

I will keep investigating on this. Tell me if you have any solution. I'll do the same.

GregTurner commented 7 years ago

I have the same problem. In my case, I have an inbound proxy that accepts Authorization: Bearer and then reconnects to a server that wants Http Basic credentials. I'm looking for a workaround but may have to patch this code.

GregTurner commented 7 years ago

This is the workaround I used. Warning: I'm hooking an unpublished event here to get access to the req object earlier. It would seem the outgoing req is cloned from the incoming BEFORE the proxyReq is emitted. In any case, it would appear like defect and an easier to repair one.

// Listen for the `start` event on `proxy`.
proxy.on('start', function (req, res) {

  // Get authorization from browser
  var authHeaderValue = req.headers.authorization;

//.... do what you need to do with that header 

  // Delete it because we add HTTP Basic later
  delete req.headers.authorization;

});
megamaddu commented 7 years ago

I had the same issue until I realized I was changing the headers incorrectly. The proxyReq arg that's passed in when you listen to the proxyReq event is a ClientRequest. The first line of the docs there explain that headers should be read and modified using helper functions (proxyReq.setHeader(...), etc). Once I started using that everything worked perfectly.

Dbroqua commented 6 years ago

Hello @spicydonuts , do you have an example of a working code?

Regards

megamaddu commented 6 years ago

No, sorry. It was pretty straightforward though; convert any code directly modifying req.headers to use req.setHeader instead. You can share what you've got if that doesn't work.

Dbroqua commented 6 years ago

Ok,

I simply made this code:

let apiProxy = require('http-proxy').createProxyServer();

router.route('/stream')
    .get(
        function(req, res) {
            apiProxy.web(req, res, {
                target: http://192.168.1.6:8082,
                auth: 'login:pass'
            });
        }
    );

The goal of my code is to show camera stream in my express app.

megamaddu commented 6 years ago

Ah, sorry, I don't think that's related to this issue.

TheSlimvReal commented 2 years ago

Having the same issue here. I am using https://www.npmjs.com/package/http-proxy-middleware and I ended up setting the authorization header manually in the onProxyReq callback