Skip to content

05. Logging in with a Google Account

Nick Doiron edited this page Mar 24, 2016 · 1 revision

Once you've made it through the process of setting up PassportJS, you can also have users log in with their accounts on other websites, using a standard known as OAuth2.

Install modules

PassportJS has several plugins called "strategies". Here's how to install one for Google sign-in into your app, once you have Passport installed:

npm install passport-google-oauth --save

Changes to User model

You should change your data model to at least these fields:

var userSchema = mongoose.Schema({
  name: { type: String, lowercase: true },
  hash: String,
  salt: String,
  googid: String
});

Changes to login.js

const GoogleStrategy = require('passport-google-oauth').OAuth2Strategy;

function confirmLogin(req, res, next) {
  // this runs once, after the callback from Google
  passport.authenticate('google', { scope: ['email'], failureRedirect: '/login' })(req, res, next);
};

function setupAuth(app, csrfProtection) {
  ...
if (process.env.GOOGLE_CONSUMER_KEY && process.env.GOOGLE_CLIENT_SECRET) {
  passport.use(new GoogleStrategy(
    {
      clientID: process.env.GOOGLE_CONSUMER_KEY,
      clientSecret: process.env.GOOGLE_CLIENT_SECRET,
      callbackURL: 'https://1batch.co/profile?justLoggedIn=true',
      passReqToCallback: true
    },
    function(request, accessToken, refreshToken, profile, done) {
      User.findOne({ googid: profile.id }, function (err, user) {
        if (!user) {
          user = new User();
          user.googid = profile.id;
          user.username = "";
          user.save(function() {
            return done(err, user);
          });
        } else {
          return done(err, user);
        }
      });
    })
  );
}
  ...
}

To get the environment variables for Google OAuth2, you will need to go to the Google Developer Console, create an app, and create an OAuth2 token. Keep these variables secret.

Normalizing Google users

When someone logs in with Google, they will be a confirmed user, but in registration we didn't set the username field. What do we do?

If you're OK with sharing user e-mails, you could set user.username = profile.email;. This is generally bad practice though. In 1batch, we look at the landing page (/profile?justLoggedIn=true) and redirect anyone whose username is still an e-mail address. We also prevent anyone from looking up a user by their e-mail.

Clone this wiki locally