Anyway to set proxy setting in passportjs?

2019-02-16 23:50发布

Currently, I am using sails framework which is based on expressjs and using passportjs(http://passportjs.org/) to do yammer authentication.

I have problem when deploying my node app on server which is behind the company proxy. It cannot connect to yammer for OAuth2 authentication.

The error is as follow:

error: failed to obtain access token (Error: connect ETIMEDOUT)
    at /root/rlps/node_modules/passport-yammer/node_modules/passport-oauth/lib/passport-oauth/strategies/oauth2.js:125:38
    at /root/rlps/node_modules/passport-yammer/lib/passport-yammer/strategy.js:72:20
    at ClientRequest. (/root/rlps/node_modules/passport-yammer/node_modules/passport-oauth/node_modules/oauth/lib/oauth2.js:129:5)
    at ClientRequest.EventEmitter.emit (events.js:95:17)
    at CleartextStream.socketErrorListener (http.js:1547:9)
    at CleartextStream.EventEmitter.emit (events.js:95:17)
    at Socket.onerror (tls.js:1437:17)
    at Socket.EventEmitter.emit (events.js:117:20)
    at net.js:441:14
    at process._tickDomainCallback (node.js:459:13)

I believe it is because the proxy is blocking the way. I tried to set everything in environment value (like http_proxy and https_proxy) but seems the code does not acknowledge them and need to config it in somewhere in passportjs instead.

So, any good way to set proxy setting in passportjs or solve this proxy issue in nodejs?

1条回答
劳资没心,怎么记你
2楼-- · 2019-02-17 00:23

Node.js doesn't use the http_proxy and https_proxy variables by default.

You have to tweak the agent parameter for the request but since you don't have control on that library you can change globally like this:

npm i tunnel --save

create a setup_proxy.js:

var env = process.env;

if (!env['http_proxy']) return;

var localUrls = [
  'http://some-internal-url.mycompany.local',
];

var url    = require('url');
var tunnel = require('tunnel');
var proxy = url.parse(env['http_proxy']);

var tunnelingAgent = tunnel.httpsOverHttp({
  proxy: {
    host: proxy.hostname,
    port: proxy.port
  }
});

var https = require('https');
var http = require('http');

var oldhttpsreq = https.request;
https.request = function (options, callback) {

  if (localUrls.some(function (u) {
    return ~u.indexOf(options.host);
  })){
    return oldhttpsreq.apply(https, arguments);
  }

  options.agent = tunnelingAgent;
  return oldhttpsreq.call(null, options, callback);
};

var oldhttpreq = http.request;
http.request = function (options, callback) {

  if (localUrls.some(function (u) {
    return ~u.indexOf(options.host);
  })){
    return oldhttpreq.apply(http, arguments);
  }

  options.agent = tunnelingAgent;
  return oldhttpreq.call(null, options, callback);
};

require this at the very beginning require('./setup_proxy').

Notice that this use the same http_proxy env variable for http and https traffic, but the code is easy to follow if you need to change.

查看更多
登录 后发表回答