DEV Community

Cover image for Google Authentication in Nodejs using Passport and Google Oauth
chryzcode
chryzcode

Posted on

Google Authentication in Nodejs using Passport and Google Oauth

Google authentication is one of the seamless and fastest modes of authenticating users in an application. It saves the user the time of filling out forms with his/her details and verifying email addresses.

In this article, we will implement Google authentication in our NodeJS application.

Create Your NodeJS Application

  • Install Node.js

    You should have Nodejs installed on your laptop and if not, check the Node.js official website, and download/ install the latest and stable release.

    To verify if node.js was successfully installed, paste the command below on your Command Line Interface (CLI) to check the version of node.js installed.

    // terminal
    node --version
    
  • Set up a simple Node.js app

    Create a directory for your application, I will create mine on the desktop using the CLI. I am using the Windows operating system and VS Code editor.

    // terminal 
    cd desktop 
    mkdir my-nodejs-app //create a project directory
    cd my-nodejs-app // navigate to the app directory
    npm init -y // create a default package.json file
    npm install express dotenv passport passport-google-oauth20 express-session // install necessary dependencies
    code . // to open the directory on my code editor (VS Code). You can do it manually.
    
  • Modify package.json file

    Configure the JSON file to get connected to the server.js file, for the application to use the ECMAScript 6 (ES6) modules, and to run a development server using the --watch flag.

    //package.json
    {
      "name": "my-nodejs-app",
      "version": "1.0.0",
      "description": "",
      "type": "module", // add this to use the ES6 
      "main": "server.js", // update this to 
      "scripts": {
        "dev": "node --watch server.js" // script to run a development server
      },
      "keywords": [],
      "author": "",
      "license": "ISC",
      "keywords": [],
      "author": "",
      "license": "ISC",
      "dependencies": {
        "dotenv": "^16.4.5",
        "express": "^4.19.2",
        "express-session": "^1.18.0",
        "passport": "^0.7.0",
        "passport-google-oauth20": "^2.0.0"
      }
    }
    
  • Create the Server

    Create an server.js file in the base of the directory to set up our project server.

    // server.js
    
    // import necessary depenencies
    import "dotenv/config";
    import express from "express";
    import passport from "passport"; 
    import { Strategy as GoogleStrategy } from "passport-google-oauth20";
    import session from "express-session";
    
    // intialize app and define the server port
    const app = express();
    const port = process.env.PORT || 8000;
    
    // a middleware to access json data
    app.use(express.json());
    
    // a view to check if the server is running properly 
    // check `http://127.0.0.1:${port}/` -> http://127.0.0.1:800
    app.get("/", (req, res) => {
      res.send(`My Node.JS APP`);
    });
    
    // a function to start the server  and listen to the port defined
    const start = async () => {
      try {
        app.listen(port, () => console.log(`server is running on port ${port}`));
      } catch (error) {
        console.log(error);
      }
    };
    
    // call the function
    start();
    
  • Generate a Google client Oauth credentials

    You have to generate a Google client Oauth credentials(Client ID and Secret), if you are new to this, check out tutorials on how to go about it.

  • Create a.envfile

    Make sure dotenv dependency is installed and imported into your server.js file. Use the format below to set the .env file.

    //.env
    // make sure these values are correct
    GOOGLE_CLIENT_ID= // your google client id
    GOOGLE_CLIENT_SECRET= // your google client client
    SESSION_SECRET= // any randome secure characters
    PORT= 8000 // define port from the env file
    
  • Createpassport.jsfile

    Create an utils folder in the project directory base and create passport.js file. This is where the connection of our Node.js app to the Google Oauth App created on the Google console takes place.

    // utils/passport.js
    
    // import necessary dependencies
    import passport from "passport";
    import { Strategy as GoogleStrategy } from "passport-google-oauth20";
    
    //initialize 
    passport.use(
      new GoogleStrategy(
        {
    
          clientID: process.env.GOOGLE_CLIENT_ID, // google client id
          clientSecret: process.env.GOOGLE_CLIENT_SECRET, // google client secret
          // the callback url added while creating the Google auth app on the console
          callbackURL: "http://localhost:8000/auth/google/callback", 
          passReqToCallback: true,
        },
    
    // returns the authenticated email profile
     async function (request, accessToken, refreshToken, profile, done) {
     // you can write some algorithms here based on your application models and all
     // an example - not related to this application
    
    /*
       const exist = await User.findOne({ email: profile["emails"][0].value });
       if (!exist) {
            await User.create({
            email: profile["emails"][0].value,
              fullName: profile["displayName"],
              avatar: profile["photos"][0].value,
              username: profile["name"]["givenName"],
              verified: true,
            });
          }
        const user = await User.findOne({ email: profile["emails"][0].value });
     return done(null, user);
    */
         return done(null, profile);
        }
      )
    );
    
    // function to serialize a user/profile object into the session
    passport.serializeUser(function (user, done) {
      done(null, user);
    });
    
    // function to deserialize a user/profile object into the session
    passport.deserializeUser(function (user, done) {
      done(null, user);
    });
    
  • Update the server.js

    The application session(middleware) must be initialized and configured to Google passport. The route for the authentication and the callback needs to be defined.

    // server.js
    
    // import necessary depenencies
    import "dotenv/config";
    import express from "express";
    import passport from "passport";
    import session from "express-session";
    // import passport.js
    import "./utils/passport.js"
    
    // intialize app and define the server port
    const app = express();
    const port = process.env.PORT || 8000;
    
    // a middleware to access json data
    app.use(express.json());
    
    // use the session middleware
    app.use(
      session({
        secret: process.env.SESSION_SECRET, // session secret
        resave: false,
        saveUninitialized: false,
      })
    );
    
    // initialize passport and session
    app.use(passport.initialize());
    app.use(passport.session());
    
    // a view to check if the server is running properly
    app.get("/", (req, res) => {
      res.send(`My Node.JS APP`);
    });
    
    // authetication route
    app.get(
      "/auth/google",
      passport.authenticate("google", {
        scope: ["email", "profile"],
      })
    );
    
    // Call back route
    app.get(
      "/auth/google/callback",
      passport.authenticate("google", {
        access_type: "offline",
        scope: ["email", "profile"],
      }),
      (req, res) => {
        if (!req.user) {
          res.status(400).json({ error: "Authentication failed" });
        }
        // return user details
        res.status(200).json(req.user);
      }
    );
    
    // a function to start the server  and listen to the port defined
    const start = async () => {
      try {
        app.listen(port, () => console.log(`server is running on port ${port}`));
      } catch (error) {
        console.log(error);
      }
    };
    
    // call the start function
    start();
    

Test your Node.JS Application

  • Run server(dev)

    Based on the custom configuration in the package.json file, to run the development use the command npm run dev

  • Authenticate a user

    Click this link http://127.0.0.1:8000/auth/google if your server is running on port 8000. You should see a page like the one below.

    After selecting an email address, it should return JSON data of that particular account.

Conclusion

I hope you found the article helpful and were able to implement the Google authentication in your Node.js application. You can check out the tutorial source code.

If yes, do well to like and share this piece and comment with me on Linkedin, Twitter and GitHub. And if you like what you read and want to show support, you can buy me coffee😉.

Top comments (0)