Nodejs Package - Using Multiple Google Strategies
I'm not sure if this is possible, but I would like to use several google strategies to use a different set of scopes depending on the link / user.
I created two separate passport variables:
passport = require('passport')
passport2 = require('passport')
I installed both of them like this:
passport.use(new GoogleStrategy({
clientID: GOOGLE_CLIENT_ID,
clientSecret: GOOGLE_CLIENT_SECRET,
callbackURL: "http://localhost:3000/auth/callback"
},
function(accessToken, refreshToken, profile, done) {
// asynchronous verification, for effect...
process.nextTick(function (){
// Changing this to return the accessToken instead of the profile information
console.log(profile.displayName);
return done(null, [{token:accessToken,rToken:refreshToken,'profile':profile}]);
});
}
));
passport2.use(new GoogleStrategy({
clientID: GOOGLE_CLIENT_ID,
clientSecret: GOOGLE_CLIENT_SECRET,
callbackURL: "http://localhost:3000/join/callback"
},
function(accessToken, refreshToken, profile, done) {
// asynchronous verification, for effect...
process.nextTick(function (){
// Changing this to return the accessToken instead of the profile information
//console.log(profile);
return done(null, [{token:accessToken,rToken:refreshToken,'profile':profile}]);
});
}
))
For my routes, I have the following:
app.get('/auth',
passport.authenticate('google', {scope: ['scopes'],
accessType:'offline', approvalPrompt:'force'})
);
app.get('/joinreq',
passport2.authenticate('google', {scope: ['different_scopes]})
);
And my callbacks look like this:
app.get('/join/callback', function(req,res){
console.log('made it to the join callback');
res.redirect('/great')
}
app.get('/auth/callback', function(req,res){
console.log('made it to the auth callback');
res.redirect('/index')
}
I can successfully authenticate with each realm successfully - the problem I am having is that my callback only applies to /join/callback
. The variable seems to be passport2
overwriting the value passport
.
Is there a way to get around this? I want a set of realms for admin users and a set of realms for everyone else.
source to share
This was solved by creating two middleware functions to define the passport variable depending on the route:
app.get('/auth',middlefunc,passport.authenticate('google',['scopes']))
app.get('/joinauth',middlefunc2,passport.authenticate('google',['scopes']))
function middlefunc(req,res,next){
passport.use(new GoogleStrategy({
clientID: GOOGLE_CLIENT_ID,
clientSecret: GOOGLE_CLIENT_SECRET,
callbackURL: "http://localhost:3000/join/callback"
},
function(accessToken, refreshToken, profile, done) {
// asynchronous verification, for effect...
process.nextTick(function (){
// Changing this to return the accessToken instead of the profile information
//console.log(profile);
return done(null, [{token:accessToken,rToken:refreshToken,'profile':profile}]);
});
}
))
}
function middlefunc2(req,res,next){
//another definition of passport.use
}
There was no need to create another variable passport
.
source to share
A slightly cleaner way is to create separate authorization points with separate names, rather than rewrite the registered strategy on every request. By default, passport gives GoogleStrategy a name "google"
, but you can supply a different name as the first argument to set the second strategy.
// set up first Google strategy
passport.use('google', new GoogleStrategy({
clientID: GOOGLE_CLIENT_ID,
clientSecret: GOOGLE_CLIENT_SECRET,
callbackURL: "http://localhost:3000/join/callback"
}, function(accessToken, refreshToken, profile, done) {
...
}
)
// Second strategy -- could use different callback URL, etc.
passport.use('google-alt', new GoogleStrategy({
...
});
app.get('/auth', passport.authenticate('google', ['scopes']))
app.get('/joinauth', passport.authenticate('google-alt', ['scopes']))
source to share