Search code examples
node.jsmongoosepassport-google-oauth2

userSchema.methods function is not getting called in mongoose


I have written userSchema.methods.generateAuthToken() function as follows

UserSchema.methods.generateAuthToken = async function()
{
    const token = jwt.sign({_id: this._id.toString()}, "ThisIsSecret");
    this.tokens = this.tokens.concat({token});
    await this.save();
    return token;
}

I am calling this function in my code while authenticating with google. following is the google authentication code

passport.use(new GoogleStrategy({
    clientID: CLIENT_ID,
    clientSecret: CLIENT_SECRET,
    callbackURL: "http://localhost:8000/auth/google/notepad"
  },
  async function(accessToken, refreshToken, profile, email, cb) {
    try
    {
      var user = await User.find({googleId: email.id});
      if(user.length === 0)
      {
        const user = new User({googleId: email.id, fullName: email.displayName, email: email.emails[0].value});
        await user.save();
      }
      return cb(undefined, user);
    }
    catch(err)
    {
      return cb(err, undefined);
    }
  }
));

router.get('/auth/google', passport.authenticate('google',{scope: ['profile','email']}));
router.get('/auth/google/notepad', 
  passport.authenticate('google', { failureRedirect: '/' }),
  async function(req, res) {
    try
    {
      const token = await req.user.generateAuthToken();
      res.cookie('authToken', token);
    }
    catch(err)
    {
      console.log(err);
    }
    res.redirect('/')
  });
router.get('/',(req,res)=>
{
    res.send();
})

I am not going to use findOrCreate() method for some reason. instead I am checking whether a user already exists or not by using find() method of mongoose. The problem is, when a user does not exists, req.user.generateAuthToken method gets called but when a user already exists then it says generateAuthToken method does not exist. It should run every time.


Solution

  • You should added this section of code so that passport saves your user info.

    passport.serializeUser((user,done)=>{
    done(null,user.id)
    })
    passport.deserializeUser((id,done)=>{
    User.findById(id,(err,user)=>done(err,user))
    })
    

    Also in the main route don't forget to add the following lines if you are using express

    app.use(passport.initialize());
    

    In a Connect or Express-based application, passport.initialize() middleware is required to initialize Passport. If your application uses persistent login sessions, passport.session() middleware must also be used.

    check the link for more info.