Can't select new Google account on relog after logging out with Google OAuth2 in Passport.js

32 Views Asked by At

Disclaimer, I've been scouring articles and documentation for about 3 hours now and nothing seems to help, that's why I'm posting.

I can't end my session when using passport google oauth2. I'm attempting to create a website that users can log in with Google. The goal is that if they leave the website and come back, they're still logged in, similar to many social media pages, YouTube, email, etc. However, if the user presses the log out button, I want them to have to select the Google account they want the next time they try to log in. Currently if they use the log out button, if they hit log in they still don't receive an option of what account to choose, and are just forced in with the last known google account.

I've tried to use prompt: 'select_account', but this forces a user to select a google account every time they come to the page, even if just navigating off for a quick second. I feel like this defeats the whole purpose of trying to use sessions and cookies if they're just going to have to authenticate every time they come to the website. I've looked at adjusting my log out button, but no matter how I change it, it doesn't change the outcome. I've tried req.logout(), req.logOut(), req.session.destroy(), and nothing seems to have an affect. I've also tried following the documentation from passport.js line for line and it still didn't work. It's making me think I have an issue somewhere else in my code that's causing a cascade of problems I don't see.

I'm entirely new to authentication, so please be patient! My app.js is below:

require('dotenv').config();
const express = require('express');
const ejs = require('ejs');
const mongoose = require('mongoose');
const session = require('express-session');
const passport = require('passport');
const passportLocalMongoose = require('passport-local-mongoose');
const GoogleStrategy = require('passport-google-oauth20').Strategy;
const findOrCreate = require('mongoose-findorcreate');

const app = express();
app.use(express.static('public'));
app.use(express.urlencoded({extended: true}));

app.set('view engine', 'ejs');

app.use(session({
    secret: process.env.SECRET,
    resave: false,
    saveUninitialized: false
}));
app.use(passport.initialize());
app.use(passport.session());

mongoose.connect(process.env.URI);
const userSchema = new mongoose.Schema({
    email: String,
    password: String,
    googleId: String,
    secret: String
});
userSchema.plugin(passportLocalMongoose);
userSchema.plugin(findOrCreate);
const User = new mongoose.model('User', userSchema);

// used for sessions & auth
passport.use(User.createStrategy());
// better serialization
passport.serializeUser((user, cb) => {
    process.nextTick(() => {
      return cb(null, {
        id: user.id,
        username: user.username,
        picture: user.picture
      });
    });
  });
passport.deserializeUser((user, cb) => {
process.nextTick(() => {
    return cb(null, user);
});
});

passport.use(new GoogleStrategy({
    clientID:     process.env.CLIENT_ID,
    clientSecret: process.env.CLIENT_SECRET,
    callbackURL: "http://localhost:3000/auth/google/secrets",
    passReqToCallback: true
  },
  (request, accessToken, refreshToken, profile, done) => {
    User.findOrCreate({ googleId: profile.id }, (err, user) => {
      return done(err, user);
    });
  }
));

app.get('/', (req, res) => {
    res.render('home');
});

app.get('/auth/google',
    passport.authenticate('google', {
        scope: ['email', 'profile'],
    //  prompt: 'select_account' // forces google account select on log in
    })
);

app.get('/auth/google/secrets',
    passport.authenticate( 'google', {
        successRedirect: '/secrets',
        failureRedirect: '/login'
}));

app.get('/login', (req, res) => {
    res.render('login');
});

app.get('/register', (req, res) => {
    res.render('register');
});

app.get('/secrets', (req, res) => {
    User.find({'secret': {$ne: null}})
    .then(foundUsers => {
        res.render('secrets', {usersWithSecrets: foundUsers});
    })
    .catch(error => {
        console.log(error);
    });
});

app.get('/submit', (req, res) => {
    if (req.isAuthenticated()){
        res.render('submit');
    } else {
        res.redirect('/login');
    }
});

app.post('/submit', (req, res) => {
    const submittedSecret = req.body.secret;
    User.findById(req.user.id)
    .then(foundUser => {
        foundUser.secret = submittedSecret;
        foundUser.save();
        res.redirect('/secrets');
    })
    .catch(error => {
        console.log(error);
    });
});

app.get('/logout', (req, res) => {
    req.logout(error => {
        if (error) {
            console.log(error);
        } else {
            res.redirect('/');
        }
    });
    // req.session.destroy(() => {
    //     req.logout(error => {
    //         if (error) {
    //             console.log(error);
    //         }
    //     });
    //     res.redirect('/');
    // });
});

app.post('/register', (req, res) => {
    User.register({username: req.body.username}, req.body.password, (err, user) => {
        if (err){
            console.log(err);
            res.redirect('/register');
        } else {
            passport.authenticate('local')(req, res, () => {
                res.redirect('/secrets');
            })
        }
    });
});

app.post('/login',
passport.authenticate('local', {failureRedirect: '/login'}),
(req, res) => {
    res.redirect('/secrets');
});

app.listen(3000, () => {
    console.log('Server started on port 3000.');
});
0

There are 0 best solutions below