Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

PassportJS - Using multiple passports within Express application

Suppose I need two different passports within one express application (e.g. user & room). So I define two separate vars:

var passport    = require('passport');
var roomPassport = require('passport');

then, I initialize them with separate passport strategies:

require('./config/passport')(passport); // pass passport for configuration
require('./config/roompassport')(roomPassport); // pass passport for configuration

the last step is to set them as Express middleware:

// required for passport
application.use(session({ secret: 'ilovepassport;-)' })); // session secret
application.use(passport.initialize({ userProperty: "user" }));
application.use(passport.session()); // persistent login sessions
application.use(roomPassport.initialize({ userProperty: "room" }));
application.use(roomPassport.session()); // persistent login sessions
application.use(flash()); // use connect-flash for flash messages stored in session`

however, if I did it like this, in fact roomPassport overrides passport and instead of having two objects - req.user and req.room, I have got just one req.room but initialized with user data.

It is important to mention that each passports (user or room) could authenticate independently from each other, i.e. there is a scenario where both objects req.user and req.room have to exist.

How to resolve this?

EDIT 1

Well, after few more hours, it seems that although I have to separate passport objects, after the call of application.use(roomPassport.initialize({ userProperty: "room" }));, things get messy - and this is because req.login() method works with the last attached passport. So instead of calling the correct passport.serializeUser method, it calls roomPassport.serializeUser method.

My next question - how to make req.login() to call the right method?

like image 501
Angel Todorov Avatar asked Sep 17 '14 17:09

Angel Todorov


People also ask

What are Passportjs strategies?

Strategies are responsible for authenticating requests, which they accomplish by implementing an authentication mechanism. Authentication mechanisms define how to encode a credential, such as a password or an assertion from an identity provider (IdP), in a request.

How do passport sessions work?

Passport uses serializeUser function to persist user data (after successful authentication) into session. The function deserializeUser is used to retrieve user data from session and perform some condition-based operations. Now all the endpoints hitting the backend server will go through passport.

Can passport use multiple strategies?

Passport's middleware is built in a way that allows you to use multiple strategies in one passport.


1 Answers

The problem your having is that the passport module exports an instantiated Passport object when you require it. And because that object is cached by node when you require it, you get the exact same object every time.

Luckily, the passport module also gives you a reference to the class, meaning you can do this.

var Passport = require('passport').Passport,
    passport = new Passport(),
    roomPassport = new Passport();

Now you should have two completely separate passport objects.

like image 185
nickclaw Avatar answered Nov 16 '22 02:11

nickclaw