How to use google oauth2 authentication with SailsJs app.

1,815 views
Skip to first unread message

David Lai

unread,
Jun 20, 2014, 12:56:26 AM6/20/14
to sai...@googlegroups.com
I'm trying to get google oauth authentication with SailsJS app.

I'm not having any luck with passport with the passport-google-oauth package.  Upon the redirect from google's permission page, it dead locks and I have no idea why.

This is how I have my controller's callback route,

  googleCallback: function(req, res) {
    passport.authenticate('local', { failureRedirect: '/login' },
        function(req, res) {
          //Does not reach this code.
          console.log("auth call back successful");
        }
    );
  }

David Lai

unread,
Jun 21, 2014, 3:32:33 AM6/21/14
to sai...@googlegroups.com
Still trying to get the hang of the differences between how a library works in SailsJS vs vanilla express.

So I think I finally got it working minus the part of serializing and deserializing user from disk.  I updated my call back handler to:

  googleCallback: function(req, res) {
    console.log("entered google callback");

    passport.authenticate('google',
        {
          failureRedirect: '/login'
        },
        function(err, usr) {

          req.logIn(usr, function() {
            res.redirect("/about");
          });
        }
    )(req, res);

  }


Looks like that passport.authenticate() method returns another method, I had to add (req, res) to invoke it.

Luc Rochefort

unread,
Jul 30, 2014, 4:35:54 PM7/30/14
to sai...@googlegroups.com
Hi David!

Have you found a solution for this?

I'm pretty new to Sails (and Node in general) and I can't seem to find any example out there that shows how to pair Sails and Passport with Google Auth.

All I want to do is a simple app that let the user sign-in with Google with a single click button, and gets redirected to a page in my app showing his display name. I just don't know to get the profile after the authentication.

req.user is undefined when I get to the profile page...

Thanks for any help.

David Lai

unread,
Jul 31, 2014, 2:30:52 PM7/31/14
to sai...@googlegroups.com
Yup. figured it out.

The main logic is in the /config/passport.js config file, here's how I have mine setup.



passport
.serializeUser(function(user, done) {

 debugLog
("serializing user:", {user: user});

 
return done(null, user);
});

passport
.deserializeUser(function(obj, done) {

 debugLog
("serializing user:", {obj: obj});

 
User.findOne(
 
//search criteria
 
{ 'id': obj.id },
 
// Callback function if found.
 
function(err, user) {

 
if( err ) {
 
// Return a logged out user if not found.
 debugLog
(err, {message: "user not found during deserialize"});
 
return done(null, false);
 
}
 
else {

 
// call done and pass it with the User Model
 
// Pass it an instance of our User model if found.
 debugLog
("Passport deserialized user", {user:user});
 
return done(null, user);
 
}
 
}
 
);
});

//callback url
var callbackUrl = "http://localhost:1337/auth/google/callback"
if(process.env.HOST_DOMAIN)
 callbackUrl
= 'https://' + process.env.HOST_DOMAIN + '/auth/google/callback';

passport
.use(
 
new GoogleStrategy(
 
// Google Settings.
 
{
 clientID
: googleApiConfig.googleAppConfig.clientID,
 clientSecret
: googleApiConfig.googleAppConfig.clientSecret,
 callbackURL
: callbackUrl
 
},

 
function(accessToken, refreshToken, profile, done) {
 process
.nextTick(function () {

 
// To keep the example simple, the user's Google profile is returned to
 
// represent the logged-in user. In a typical application, you would want
 
// to associate the Google account with a user record in your database,
 
// and return that user instead.
 debugLog
("Found profile", {profile: profile});

 
User.findOrCreate(
 
//Search criteria
 
{ googleId: profile.id },
 
//Insertion criteria when search fails.
 
{
 googleId
: profile.id,
 uuid
: uuid.v1()
 
},
 
// Call back function.
 
function (err, user) {
 
//update refresh token for the user'
 user
.googleAccessToken = accessToken;

 
// Only update refresh token if one is provided.
 
if(refreshToken)
 user
.googleRefreshToken = refreshToken;

 user
.save(function(err){
 errLog
(err)
 
});

 
return done(err, user);
 
}
 
); //end User.findOrCreate()

 
}); // end of nextTick()
 
}//end callback function
 
) // end GoogleStrategy()
);




module.exports = {
 http
: {
 customMiddleware
: function(app){
 debugLog
('initializing express middleware for passport');
 app
.use(passport.initialize());
 app
.use(passport.session());
 
}
 
}
};

Alberto Souza

unread,
Jul 31, 2014, 2:36:57 PM7/31/14
to David Lai, sai...@googlegroups.com
A tip for passport ...

Use it in polices

I think https://www.npmjs.org/package/sails-generate-auth also uses polices for current logged in user check.


Alberto Souza
:Programador JS, Node, PHP e Drupal
We.js <- eu que fiz :)
:Site pessoal

Message has been deleted

Henry Stella

unread,
Aug 6, 2014, 2:43:56 AM8/6/14
to sai...@googlegroups.com
Has anyone used Waterlock for their authentication?

The project now has google auth.

I am thinking of using Waterlock instead of Passport because it has a Sails generator, built in nodemailer support and has JSON Web Tokens.

voltron

unread,
Aug 14, 2014, 12:00:10 PM8/14/14
to sai...@googlegroups.com
Thanks for the link Henry. I will try waterlock out.
Reply all
Reply to author
Forward
0 new messages