Building Login with Google in Zero

Zero already implements express, passport and sessions. This means you don't have to fiddle with most of passport's configurations.

In this post, I will implement a Google login using passport-google-oauth module.

Get Auth Key From Google Console

The first step is to head over to Google Developers Console and create new OAuth client ID. You may also need to enable Google+ API in the developer console, otherwise user profile data may not be fetched. Google supports authentication with both oAuth 1.0 and oAuth 2.0.

Once you have Client Id and Client Secret, save them somewhere as we will need them.

Add a Passport Strategy

Create a file named _passport.js. This will be a common module used by our passport auth handler and callback handler. The _(underscore) prevents this file from being exposed as a route. Add the following strategy to this file:

var GOOGLE_ID="YOURGOOGLEID.apps.googleusercontent.com",
GOOGLE_SECRET="Rj2_vDGoogleSecretgXxB4e"
var GoogleStrategy = require('passport-google-oauth').OAuth2Strategy,
passport = require("passport")
// Use the GoogleStrategy within Passport.
// Strategies in passport require a `validate` function, which accept
// credentials (in this case, an OpenID identifier and profile), and invoke a
// callback with a user object.
passport.use(new GoogleStrategy({
clientID: GOOGLE_ID,
clientSecret: GOOGLE_SECRET,
callbackURL: "http://localhost:3000/callback"
}, function (accessToken, refreshToken, profile, done) {
return done(null, {
name: profile.displayName,
email: profile.emails[0].value
})
})
)
module.exports = passport
  • You need to edit GOOGLE_ID and GOOGLE_SECRET with the keys we generated earlier.

Login API and Callback

Once that's set, we will now make a API which user can visit to start their login flow. Let's say http://localhost:3000/login. Create a login.js file in your project and add the following code:

var passport = require("./_passport")
module.exports = passport.authenticate('google', {
scope: ['profile', 'email'],
session: false
})

Visiting this path will redirect the user to Google's login screen, after which they will be redirected back to our /callback URL we defined in our _passport.js. Let's make that path now:

Create a file named callback.js and add the following code:

var passport = require("./_passport")
module.exports = passport.authenticate('google', {
successRedirect: "/",
failureRedirect: '/error'
})

This simply adds the user's profile to our session store. So it becomes available in req.user in any other files.

Be sure to go back to Google console and add your callback path (the one you defined in _passport.js, both local and your production website's) in the "Authorized redirect URIs" .

Using User Info

Once user is logged in, you can use the user's info (name, email, etc) in your pages and APIs. Here is a simple React page that prints user's name if the user is logged in:

// ./index.jsx
// This is a React component, which gets `props.user`
// and displays either a login button or the logged-in user's info
export default ({user})=>{
if (!user){
return (
<a href="/google-login-nodejs/login">Login with Google</a>
)
}
else{
return (
<b>Logged in as {user.name} ({user.email})</b>
)
}
}

That's it! You can also implement other social logins using the above example.

Where are sessions stored?

By default, zero stores sessions in a local file. You would use a database when deploying your app to server. Read the docs on sessions for more info on this.

Complete Example

You can see the complete example here.

Best Practices

You should move GOOGLE_ID and GOOGLE_SECRET to environment variables. Keeping them in your code is a bad practice.


Copyright © 2019 Remote Interview, Inc. All rights reserved.