Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Anyway to set proxy setting in passportjs?

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?

like image 329
A-letubby Avatar asked Dec 12 '13 02:12

A-letubby


1 Answers

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.

like image 85
José F. Romaniello Avatar answered Nov 09 '22 14:11

José F. Romaniello