Modify headers of proxied request
Asked Answered
F

2

5

I'm IP restricting a pure client-side CORs demo application which interacts with an authenticated third-party API. I've got a "middleware" server running which I use to proxy requests from the CORs app to the third-party API, but I am having trouble injecting Basic Authentication credentials into those proxied requests.

isAllowed = (req, res, next) -> # Do IP check here.

base64Encode = (unencoded) -> new Buffer(unencoded or '').toString 'base64'

app.all "/demoproxy/*", isAllowed, (req, res) ->

  req.url = "/" + req.url.split("/").slice(2).join("/")

  userPass = base64Encode "#{process.env.DEMO_USERNAME}:#{process.env.DEMO_PASSWORD}"

   # This doesn't work.
   # res.setHeader 'Authorization',  "Basic #{userPass}"

   # This doesn't work either.
   ###res.oldWriteHead = res.writeHead

   res.writeHead = (statusCode, headers) ->

     headers = { }
     headers['Authorization'] = "Basic #{userPass}"
     res.oldWriteHead statusCode, headers###

    proxy = new httpProxy.HttpProxy
      target:
        host: 'remote-api.com'
        port: 80

    proxy.proxyRequest req, res

What is the proper way to do this?

Ferreby answered 18/6, 2013 at 17:8 Comment(0)
C
13

I think you want to set the authorization header on the request (req) object in this case, not the response (res). If remote-api.com is what needs to be authenticated against then it needs to know that with the request you send to it. Maybe try the following before making the proxy.proxyRequest request

req.headers["authorization"] = "Basic #{userPass}"

With the req object there isn't a setHeader function, the headers property is just a javascript object/map. Hope that helps out...

Championship answered 20/6, 2013 at 16:49 Comment(2)
So, I tried that. But it doesn't come through the same as other Basic Auth? Updated question.Ferreby
Have you tried setting req.headers['authorization'] as well? According to the node HTTP docs (nodejs.org/api/http.html#http_message_headers), the headers object has all lower-cased, so if it's not working when setting the upper-cased header, perhaps the proxy is only looking at the lower-cased version.Hellenism
H
0

Here is some code that works for me, as an example:

# Demo server requiring basic authentication
servAuth = require("http").createServer (req, res) ->
  if auth = req.headers?.authorization
    res.statusCode = 200
    res.end "Good job, you sent '#{auth}'"
  else
    res.statusCode = 401
    res.end "How about you authenticate first?"
servAuth.listen(8090)

# Proxy server which checks the IP address and then proxies the request
servProxy = require("http-proxy").createServer (req, res, proxy) ->
  checkIP req, (err, isOK) ->
    # something wrong happened even with the IP address checking
    if err
      res.statusCode = 500
      res.end "Sorry, everything got fargled", "ascii"
    # IP address not allowed
    else if not isOK
      res.statusCode = 403
      res.end "You ain't from around here, are you?", "ascii"
    # all good, proxy the request with basic auth added
    else
      userPass = new Buffer("#{process.env.USERNAME}:#{process.env.PASSWORD}", "ascii")
      userPass = userPass.toString("base64")
      req.headers.authorization = "Basic #{userPass}"
      proxy.proxyRequest req, res, {
        host: "localhost"
        port: 8090
      }
servProxy.listen(8080)

# asynchronous IP address checking
checkIP = (req, done) ->
  # TODO: implement whatever custom IP checking
  # this example just says everything is OK
  done( null, true )
Hellenism answered 1/7, 2013 at 10:43 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.