はじめに
社内でフロント向け開発ツールを作成していた時、クロスドメイン問題を回避するためにフォワードプロキシが必要になった。
やりたいこと
クライアントからのHTTPリクエストを受け、認証付き社内プロキシを経由して別サーバへフォワードする。
リクエストとレスポンスは改変しない。そのまま横流しするだけ。
使ったもの
- node(v8.9.3)
- http-proxy
修正前ソース
server.js
const httpProxy = require('http-proxy');
const http = require('http');
var proxy = httpProxy.createProxyServer({});
// http server
var httpServer = http.createServer(function (req, res) {
res.setHeader('tekitou', 'tekitou');
var opt = {target:'http://tekitou.com'};
proxy.web(req, res, opt, function (err) {
console.log(" !! translate error. ");
console.log(err);
res.write("<p> Translate error.</p>");
res.write("<p>Host name : " + req.headers.host + "</p>");
res.end();
return;
});
return;
});
var port=1234
httpServer.listen(port, function () {
console.log("-- start forward proxy server(http) . listen " + port + " port. --");
});
はまったところ
- 認証付きの社内プロキシが通らない
そのままhttp-proxyでプロキシを作っても、認証付きの社内プロキシは通してくれない。
tunnnelを使って認証プロキシのagentをoptionに付与する必要あり。
<改変後>
server.js
const httpProxy = require('http-proxy');
const http = require('http');
// new!
const tunnel = require('tunnel');
var tunnelingAgent = tunnel.httpOverHttp({
proxy: {
host: 'hoge,co.jp',
port: 1111,
proxyAuth: 'proxyid:proxypass'
}
});
var proxy = httpProxy.createProxyServer({});
// http server
var httpServer = http.createServer(function (req, res) {
res.setHeader('tekitou', 'tekitou');
// new!
var opt = {target:'http://tekitou.com' , agent:tunnelingAgent };
proxy.web(req, res, opt, function (err) {
console.log(" !! translate error. ");
console.log(err);
res.write("<p> Translate error.</p>");
res.write("<p>Host name : " + req.headers.host + "</p>");
res.end();
return;
});
return;
});
var port=1234
httpServer.listen(port, function () {
console.log("-- start forward proxy server(http) . listen " + port + " port. --");
});
- フォワード先をhttpsに向けると通らない
optionにsecure=falseとchangeOrigin=trueを付与したら通った。
さらに、tunnnelのhttpOverHttpsのagentが必要。
<改変後>
server.js
const httpProxy = require('http-proxy');
const http = require('http');
const tunnel = require('tunnel');
var tunnelingAgent = tunnel.httpOverHttp({
proxy: {
host: 'hoge,co.jp',
port: 1111,
proxyAuth: 'proxyid:proxypass'
}
});
// new!!
var tunnelingAgentForHttps = tunnel.httpOverHttps({
proxy: {
host: 'hoge,co.jp',
port: 1111,
proxyAuth: 'proxyid:proxypass'
}
});
var proxy = httpProxy.createProxyServer({});
// http server to https
var httpServer = http.createServer(function (req, res) {
res.setHeader('tekitou', 'tekitou');
var opt =
{ target:'https://tekitou.com',
agent : tunnelingAgentForHttps ,
secure : false,
changeOrigin : true
};
proxy.web(req, res, opt, function (err) {
console.log(" !! translate error. ");
console.log(err);
res.write("<p> Translate error.</p>");
res.write("<p>Host name : " + req.headers.host + "</p>");
res.end();
return;
});
return;
});
var port=1234
httpServer.listen(port, function () {
console.log("-- start forward proxy server(http) . listen " + port + " port. --");
});
さいごに
踏み込んだ説明がなくてごめんなさい。
スマートな方法があったら教えてください。