I am getting Error: req#logout requires a callback function when trying to call /logout.
I expect to logout and then when I try to authenticate again, to see the actual Google OAuth2.0 screen and not just “You are authenticated”.
I assume this happens because of the fact I have a session alive, hence I added req.logOut and req.session.destroy to get rid of it, but if I uncomment req.logOut I keep getting the error.
I tried to redefine /logout as in the code but I am still getting the same error.
index.js
const PORT = 3000;
require("dotenv").config();
const express = require("express");
const app = express();
const mongoose = require("mongoose");
const passport = require("passport");
const { isLoggedIn } = require("./middlewares/authMiddleware");
const session = require("express-session");
const bodyParser = require("body-parser");
// parse application/json
app.use(bodyParser.json());
// parse application/x-www-form-urlencoded
app.use(bodyParser.urlencoded({ extended: false }));
app.use(express.json());
app.use(
session({
secret: process.env.SESSION_SECRET,
resave: false, // don't save session if unmodified
saveUninitialized: false, // don't create session until something stored
})
);
app.use(passport.initialize());
app.use(passport.session());
// Import routes
const userRoute = require("./app/routes/UserController");
// Route middleware
app.use("/api/v1/users", userRoute);
app.get("/", (req, res) => {
res.send('<a href="/auth/google">Authenticate with Google</a>');
});
app.get(
"/auth/google/callback",
passport.authenticate("google", {
successRedirect: "/protected",
failureRedirect: "/auth/failure",
})
);
app.get("/auth/failure", (req, res) => {
res.send("Failed to authenticate..");
});
app.get(
"/auth/google",
passport.authenticate("google", { scope: ["email", "profile"] })
);
app.get("/protected", isLoggedIn, (req, res) => {
res.send("You are authenticated");
});
app.get("/logout", (req, res, next) => {
if (req.session) {
req.logOut();
req.session.destroy();
res.redirect("/");
}
});
/**
* Configure mongoose
*/
// mongoose.Promise = global.Promise;
app.locals.db = mongoose
.connect(process.env.DB_CONNECT, {
useNewUrlParser: true,
useUnifiedTopology: true,
})
.then(() => {
console.log("Connected to Database");
app.listen(PORT, () => {
console.log(`Server listening on port ${PORT}`);
});
});
authMiddleware.js
const passport = require("passport");
const GoogleStrategy = require("passport-google-oauth20").Strategy;
const User = require("../app/models/User");
passport.serializeUser((user, done) => {
done(null, user);
});
passport.deserializeUser(function (user, done) {
done(null, user);
});
passport.use(
new GoogleStrategy(
{
clientID: process.env.GOOGLE_CLIENT_ID,
clientSecret: process.env.GOOGLE_CLIENT_SECRET,
callbackURL: process.env.GOOGLE_CALLBACK_URL,
},
function (accessToken, refreshToken, profile, done) {
User.findOne({ "oauth.googleId": profile.id })
.then((existingUser) => {
if (existingUser) {
return done(null, existingUser);
} else {
var newUser = new User({
name: profile.givenName,
surname: profile.familyName,
email: profile.emails[0].value,
username: profile.displayName,
oauth: {
googleId: profile.id,
displayName: profile.displayName,
firstName: profile.name.givenName,
lastName: profile.name.familyName,
email: profile.emails[0].value,
},
});
newUser
.save()
.then((newUser) => {
return done(null, newUser);
})
.catch((err) => {
return done(err);
});
}
})
.catch((err) => {
return done(err);
});
}
)
);
module.exports.isLoggedIn = function (req, res, next) {
req.user ? next() : res.sendStatus(401);
};
module.exports.passport = passport;