Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

This is a great library but how you handle subdomains? #59

Open
damianofusco opened this issue May 15, 2015 · 5 comments
Open

This is a great library but how you handle subdomains? #59

damianofusco opened this issue May 15, 2015 · 5 comments

Comments

@damianofusco
Copy link

I have an app where a use could login on: subX.domain.com
and another user could login on subY.domain.com

The fact that the callbackURL is setup initially and bound to the app, makes it impossible for passport to authenticate a user correctly. Ideally, the twitter strategy handler (your second function passed into TwitterStrategy) should be set by user.

I guess this is not easy change or might not even be possible with passport.

Damiano

@Mithgol
Copy link

Mithgol commented Jun 26, 2016

It's actually quite possible to handle subdomains by Passport.

While Passport itself is fine with that, it's the examples given in Passport's documentation that are too simplified and thus they cannot handle several subdomains.

These examples declare their passport variable by merely requiring the module (var passport = require('passport')) and then they use that variable in passport.initialize(); it's also not unlikely to use that variable to declare the strategy as well, such as the following:

passport.use(new passportTwitterStrategy(
   {
      consumerKey: 'XXXXXXXXXXXXXXXXXXXXXXXXX',
      consumerSecret: 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX',
      callbackURL: 'http://' + someOptions.subdomain + '/callbackTwitter'
   },
   function(token, tokenSecret, profile, done){
      done(null, profile);
   }
));

There are two problems with that.

Problem 1. Most of us tend to require Node.js modules at the very beginning of our scripts. Here we'd expect to drop var passport = require('passport') on top — and we are done.

However, if your script declares a function that accepts some parameters (such as the desired name of a subdomain) and returns, for example, an Express app for that subdomain, then you'd design your script (yourSubdomainGenerator.js) to export that function and to be later called in a following fashion:

var express = require('express');
var vhost = require('vhost');
var app = express();

app.use(vhost(
   'subX.domain.com',
   require('./yourSubdomainGenerator.js')({
      subdomain: 'subX.domain.com'
   })
));

app.use(vhost(
   'subY.domain.com',
   require('./yourSubdomainGenerator.js')({
      subdomain: 'subY.domain.com'
   })
));

Therefore you'd want to keep passport variable local in the function that is exported from yourSubdomainGenerator.js. So that each function call creates its own passport.

Problem 2. Node.js module system is a caching system. You may call require('passport') twice for your two subdomains, but you are getting the same JavaScript object. Any attempt to passport.use for the second subdomain will then affect the first subdomain, which is wrong.

There is a two-step solution that works around both of these two problems:

  1. Replace var passport = require('passport') with var passportAuthenticator = require('passport').Authenticator on top of your file.

  2. Use passportAuthenticator as a constructor and assign an independently created object to your local passport variable (such as var passport = new passportAuthenticator()) for each of your subdomains.

@Mithgol
Copy link

Mithgol commented Jun 26, 2016

That exported Authenticator property is actually an exposed constructor as seen in lib/index.js of Passport.

@Mithgol
Copy link

Mithgol commented Jun 26, 2016

I also believe that the above solution might help most people that experience the issue #12 in the case where it's subdomain vs. www.subdomain in their applications.

@Mithgol
Copy link

Mithgol commented Jun 26, 2016

The same problem is also seen in jaredhanson/passport#27, jaredhanson/passport#286, jaredhanson/passport#402.

@arenddeboer
Copy link

Thanks a bunch @Mithgol ! My express app (nuxt) serves multiple domains, now I can authenticate with any strategy configuration depending on the req.hostname (or x-forwarded-host)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants