Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

Sorry, you do not have permission to ask a question, You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please type your username.

Please type your E-Mail.

Please choose an appropriate title for the post.

Please choose the appropriate section so your post can be easily searched.

Please choose suitable Keywords Ex: post, video.

Browse

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

Querify Question Shop: Explore Expert Solutions and Unique Q&A Merchandise

Querify Question Shop: Explore Expert Solutions and Unique Q&A Merchandise Logo Querify Question Shop: Explore Expert Solutions and Unique Q&A Merchandise Logo

Querify Question Shop: Explore Expert Solutions and Unique Q&A Merchandise Navigation

  • Home
  • About Us
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • About Us
  • Contact Us
Home/ Questions/Q 2310

Querify Question Shop: Explore Expert Solutions and Unique Q&A Merchandise Latest Questions

Author
  • 61k
Author
Asked: November 26, 20242024-11-26T04:14:08+00:00 2024-11-26T04:14:08+00:00

Setting up Passport Google OAuth2.0: Possible Causes of Internal Server Error

  • 61k

I have been working on a side project that builds with the MERN (MongoDB, Express, React, Node) tech stack and using Passport.js, specifically Google oauth2.0. The project is deployed on Heroku (a backend application hosting cloud platform) and it is using the cloud storage database through MongoDB Atlas.

During the set up of the passport oauth2.0, I have encountered several internal server errors that have taken some time to debug. I decided to include all the possible causes of internal server error I encountered below:

Cause #1: ID & SECRET are not added to config vars

CLIENT_ID and CLIENT_SECRET from the Google Cloud Console (should be found in the Credentials – OAuth 2.0 Client IDs – for Google Oauth API) are not added to the config vars in Heroku (or any other hosting platforms).

Config vars are similar to the variables that we placed in the .env file. They contain the secret information that we do not want the public to know for security reason.

Heroku Config Vars

Cause #2: CallbackURL does not match up with the Redirect_uri

CallbackURL is the redirected url after an user is authenticated.

Redirect_uri should be added to the Authorized redirect URIs
in the Google Cloud Console (should be found in the Credentials – OAuth 2.0 Client IDs – for Google Oauth API). It is crucial to confirm they match up.

passport.use(new GoogleStrategy({     clientID: process.env.GOOGLE_CLIENT_ID,     clientSecret: process.env.GOOGLE_CLIENT_SECRET,     callbackURL: "http://www.example.com/auth/google/callback"   },    function(accessToken, refreshToken, profile, cb) {     User.findOrCreate({ googleId: profile.id }, function (err, user) {       return cb(err, user);     });   } )); 
Enter fullscreen mode Exit fullscreen mode

Cause #3: Routing are setup incorrectly

This is the cause that took me the longest time to debug when working on my project. Since the project is built with MERN, its frontend is using the React frontend platform, and its backend server side is using the Express Node.js web application platform.

While working in the local environment especially, if we are simply setting up the routes, we sometimes got confused between the communication of the frontend and the backend. I got stuck in this for a long period of time until I found out the correct routing setup for the communication between the frontend platform and the backend server. Please see the attempt below:

Local Environment – the origin url is different when communicating between the frontend and the server.

Frontend url: http://localhost:3000

Backend (server) url: http://localhost:3001

  • Frontend (3000) —> Backend (3001)

When signing in/signing out of an application, in the frontend, the route should be set up to communicate to the backend. So the route origin url should be set to http://localhost:3001, see example below:

//Frontend (React) main.js //Functions to sign in/sign out of Google      const handleSignInGoogle = () => {         window.open("http://localhost:3001/auth/google", "_self");          }      const handleLogOutGoogle = () => {         window.open("http://localhost:3001/auth/logout", "_self");        } 
Enter fullscreen mode Exit fullscreen mode

The callbackURL should be set to 3001 origin url as well:

//server.js  passport.use(new GoogleStrategy({     clientID: process.env.GOOGLE_CLIENT_ID,     clientSecret: process.env.GOOGLE_CLIENT_SECRET,     callbackURL: "http://localhost:3001/auth/google/callback"   },    function(accessToken, refreshToken, profile, cb) {     User.findOrCreate({ googleId: profile.id }, function (err, user) {       return cb(err, user);     });   } )); 
Enter fullscreen mode Exit fullscreen mode

  • Frontend (3000) <— Backend (3001)

Once the user is authenticated successfully, they would be redirected to a secret page (only authenticated users can access):

//server.js app.get("/auth/google/callback",    passport.authenticate("google", { failureRedirect: "/login" }),   function(req, res) {     // Successful authentication, redirect to secret page.     res.redirect("http://localhost:3000/secret-page");  //redirect back to the frontend secret page   }); 
Enter fullscreen mode Exit fullscreen mode

Once the user is signed out, they would be redirected to the home page:

//server.js const CLIENT_HOME_PAGE_URL = "http://localhost:3000";   app.get("/auth/logout", function(req, res){     if (req.user) {       req.session.destroy();       req.logout();       res.redirect(CLIENT_HOME_PAGE_URL); //redirect back to the frontend home page     }else {       res.send("user is already logged out!");     } }); 
Enter fullscreen mode Exit fullscreen mode

~~

Live Environment – the origin url should be consistent (the same) for both the frontend and the server.

  • Frontend —> Backend
//main.js     const handleSignInGoogle = () => {         window.open("https://example.herokuapp.com/auth/google", "_self");      }      const handleLogOutGoogle = () => {         window.open("https://example.herokuapp.com/auth/logout", "_self");      } 
Enter fullscreen mode Exit fullscreen mode

//server.js passport.use(new GoogleStrategy({     clientID: process.env.GOOGLE_CLIENT_ID,      clientSecret: process.env.GOOGLE_CLIENT_SECRET,     callbackURL: "https://example.herokuapp.com/auth/google/callback",        userProfileURL: "https://www.googleapis.com/oauth2/v3/userinfo"   },    function(accessToken, refreshToken, profile, cb) {     User.findOrCreate({ googleId: profile.id }, function (err, user) {       return cb(err, user);     });   } )); 
Enter fullscreen mode Exit fullscreen mode

  • Frontend <— Backend
//server.js app.get("/auth/google/callback",    passport.authenticate("google", { failureRedirect: "/login" }),   function(req, res) {     // Successful authentication, redirect to secret page.     res.redirect("/secret-page");    }); 
Enter fullscreen mode Exit fullscreen mode

//server.js const CLIENT_HOME_PAGE_URL = "https://example.herokuapp.com";  app.get("/auth/logout", function(req, res){     if (req.user) {       req.session.destroy();       req.logout();       res.redirect(CLIENT_HOME_PAGE_URL);     }else {       res.send("user is already logged out!");     } }); 
Enter fullscreen mode Exit fullscreen mode

Cause #4: Mongo Server Error

MongoServerError: E11000 duplicate key error collection ... dup key: { username: null } 
Enter fullscreen mode Exit fullscreen mode

Basically it means you have already had an user with an username set to null. You can read more about this type of error here.

Fastest way to resolve this error is to add an additional field – username – in the User schema (where all the users login info is stored once authenticated successfully), see example below:

const userSchema = new mongoose.Schema({   googleId: String,   username: String,   fullname: String,   firstname: String,   profileImgUrl: String   });   passport.use(new GoogleStrategy({     clientID: process.env.GOOGLE_CLIENT_ID,      clientSecret: process.env.GOOGLE_CLIENT_SECRET,     // callbackURL: "https://example.herokuapp.com/auth/google/callback", //Live      callbackURL: "http://localhost:3001/auth/google/callback", //Local     userProfileURL: "https://www.googleapis.com/oauth2/v3/userinfo"   },   function(accessToken, refreshToken, profile, cb) {     User.findOrCreate({          googleId: profile.id,         username: profile.emails[0].value,         fullname: profile._json.name,         firstname: profile._json.given_name,         profileImgUrl: profile.photos[0].value     }, function (err, user) {       return cb(err, user);     });   } )); 
Enter fullscreen mode Exit fullscreen mode

Cause #5: Mongoose-findorcreate plugin (npm package)

This is a recent cause I found in August 2022. I have been receiving the mongoose duplicate key error. Instead of getting null, I am getting {username: myemailaddress@gmail.com}. I have tried to find information online but unable to find any relevant info.

MongoServerError: E11000 duplicate key error collection ... dup key: { username: myemailaddress@gmail.com } 
Enter fullscreen mode Exit fullscreen mode

When checking the npm package, I realized the recent update of the package is a few years ago. It is kind of obsolete. I am guessing the cause of the duplicated key error could be related to this package, but I am not 100% sure.

In order to resolve this issue, I have followed the guidance from a blog post to update the find or create logic as below. Using the Mongoose methods – findOne and create– this has resolved the duplicated key issue.

passport.use(new GoogleStrategy({     clientID: process.env.GOOGLE_CLIENT_ID,      clientSecret: process.env.GOOGLE_CLIENT_SECRET,     // callbackURL: "https://example.herokuapp.com/auth/google/callback", //Live      callbackURL: "http://localhost:3001/auth/google/callback", //Local     userProfileURL: "https://www.googleapis.com/oauth2/v3/userinfo"   },   function(accessToken, refreshToken, profile, cb) {       const newUser = {         googleId: profile.id,         username: profile.emails[0].value,         fullname: profile._json.name,         firstname: profile._json.given_name,         profileImgUrl: profile.photos[0].value       };       try {         let user = await User.findOne({ googleId: profile.id });          if (user) {           cb(null, user);         } else {           user = await User.create(newUser);           cb(null, user);         }       } catch (err) {         console.log(err);       }   } )); 
Enter fullscreen mode Exit fullscreen mode

Cause #6: Unused or Not Needed Method

This medium article (twitter oauth using passport) is one of the references I use when setting up the Google Oauth2.0 for my side project. It is extremely helpful for beginners!

This internal server error was not found while testing in the local environment until it was set live. In order to find out what causes the issue, I have used “heroku log” to find out the building process of the web application and found the issue was coming from cors method.

As found for the live environment, there isn't a need to set up cors to allow the server to accept request from different origin. In the article, cors is setup for the local environment server, without any mention regarding if it is needed in the live environment. Based on what I found from my side project, cors is not needed in the live environment.


There could be other possible causes of your internal server error that I might not have included in this blog post. Hopefully, this gives you some ideas regarding the possible causes of an internal server error when setting up the passport Google oauth2.0 authentication for your web application.

authenticationbeginnersdebuggingwebdev
  • 0 0 Answers
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

Sidebar

Ask A Question

Stats

  • Questions 4k
  • Answers 0
  • Best Answers 0
  • Users 1k
  • Popular
  • Answers
  • Author

    How to ensure that all the routes on my Symfony ...

    • 0 Answers
  • Author

    Insights into Forms in Flask

    • 0 Answers
  • Author

    Kick Start Your Next Project With Holo Theme

    • 0 Answers

Top Members

Samantha Carter

Samantha Carter

  • 0 Questions
  • 20 Points
Begginer
Ella Lewis

Ella Lewis

  • 0 Questions
  • 20 Points
Begginer
Isaac Anderson

Isaac Anderson

  • 0 Questions
  • 20 Points
Begginer

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help

Footer

Querify Question Shop: Explore Expert Solutions and Unique Q&A Merchandise

Querify Question Shop: Explore, ask, and connect. Join our vibrant Q&A community today!

About Us

  • About Us
  • Contact Us
  • All Users

Legal Stuff

  • Terms of Use
  • Privacy Policy
  • Cookie Policy

Help

  • Knowledge Base
  • Support

Follow

© 2022 Querify Question. All Rights Reserved

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.