Search code examples
node.jsexpress-session

Logout not working - nodejs express-session


I can't get the logout function to work correctly and remove the session from the mongodb. I'm able to store the session. logout was initially req.session.destroy(); but that kept returning an error. (destroy undefined) I'm pretty new to nodejs/javascript, I'm trying to learn my apologies in advance for any ignorance!
Any help would be appreciated!!

app.js

const express = require('express'), url = require('url');
const path = require('path');
const dotenv = require('dotenv');
const connectToDatabase = require('./src/db/mongoose');
const helmet = require('helmet');
const router =  require('./src/routes/routes');
const openApiDocumentation = require('./src/swagger/openApiDocumentation');
const swaggerUi = require('swagger-ui-express');
const cors = require('cors');
const bodyParser = require("body-parser");
var app = express();
const session = require('express-session');
const MongoStore = require('connect-mongo');
const port = process.env.PORT || 3000;
dotenv.config();
 connectToDatabase(); //This removed to simplify the connection



app.use(express.json());
app.use(express.static('src/css'));
app.use(express.static('src/js'));
app.use(express.static('scripts'));
app.use(express.static('controllers'));
app.use(express.static(__dirname + '/views'));
app.use(express.static("views")); 
app.use('/', express.static(path.join(__dirname, 'views'),{extensions:['html']}));
app.use('/api', swaggerUi.serve, swaggerUi.setup(openApiDocumentation));




app.use(function(req, res, next){
  res.locals.user = req.user;
  next();
});


app.use("/v1/login", session({
  name: 'auth',
  secret: 'mykey',
  httpOnly: true,
  secure: true,
  maxAge: 1000 * 60 * 60 * 7,
  resave: false,
  saveUninitialized: true,
  store: MongoStore.create({
      mongoUrl: '<redacted>'
  })
}));

app.get('/name', (req, res) => {
    let name;

    if (!req.session) {
        return res.status(404).send();
    }

    name = req.session.user.name;

    return res.status(200).send({name});
})
app.use(function (req, res, next) {
  res.locals.session = req.session;
  next();
});
router.get("/vl/login", function(req, res) {
  if (
    typeof reqsession.user != "object" || (
    typeof req.session.user.name == "undefined" &&
    typeof req.session.user.password == "undefined")
  ) {
    res.render("pages/index");
  }
  res.redirect("Login");
});

app.use(function(req, res, next) {
  console.log('%s %s', req.method, req.url);
  next();
});

  app.engine('.html', require('ejs').__express);

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


  


// index page
app.get('/', function(req, res) {
  res.render('pages/index');
});

// about page
app.get('/about', function(req, res) {
  res.render('pages/about');
});



app.use(function(req, res, next){
  res.locals.user = req.user;
  next();
});


app.use(cors());
app.use(express.urlencoded({ extended: true }));
app.use(helmet());
app.use('/v1', router);

app.use(bodyParser.urlencoded({ extended: false })); 
app.use(bodyParser.json());




app.listen(port, () => console.log(`Server is running on Port: ${port}`));

userController.js

  login: async (req, res) => {

        const { userName, password } = req.body
        const user = await userModel.findOne({ userName }).lean()
        if (!user) {
            return res.json({ status: 'error', error: 'Invalid username/password' })

        }
        if (await bcrypt.compare(password, user.password)) {
            // the username, password combination is successful
            const token = jwt.sign(
                {
                    id: userModel._id,
                    userName: userModel.userName
                },
                JWT_SECRET
            )

            const { name } = req.body;
            req.session.user = {
                name,
                isLoggedIn: true
            }

            try {
                await req.session.save();
            } catch (err) {
                console.error('Error saving to session storage: ', err);
                return next(new Error('Error creating user'));
            }


            return res.json({ status: 'ok', data: token })

        }

        res.json({ status: 'error', error: 'Invalid username/password' })
    },

    logout: async (req, res, next) => {
        try {
            await  await req.session == null;
        } catch (err) {
            console.error('Error logging out:', err);
            return next(new Error('Error logging out'));
        }
        
        return res.json({ status: 'ok'})
      },

routes.js

const express = require('express');
const router = express.Router();

const newUser = require('../controllers/userController');
const company = require('../controllers/companyController');
const upload = require('../controllers/upload');
const auth = require('../middleware/auth');



/* GET response for '/'/*
router.get('/', (req, res) => {
    
    res.redirect('/');
}) */

//generate token
router.get('/token', newUser.generateToken);

//login
router.post('/login', newUser.login);

//logout
router.post('/logout',  newUser.logout);

//create service user
router.post('/addServiceUser', newUser.addServiceUser);

//Add user
router.post('/users', newUser.addUser);

//remove user
router.delete('/users/:id',auth, newUser.removeUser);

//Get All users
router.get('/users',auth, newUser.getAllUsers);

//Get User
router.get('/user/:id',auth, newUser.getUser);

//Get first name
router.get('/users/:id/firstName',auth, newUser.getUserFirstName);

//Set first name
router.put('/users/:id/firstName',auth, newUser.setUserFirstName);

//Get last name
router.get('/users/:id/lastName',auth, newUser.getUserLastName);

//Set last name
router.put('/users/:id/lastName',auth, newUser.setUserLastName);

//Get user email
router.get('/users/:id/email',auth, newUser.getUserEmail);

//set user email
router.put('/users/:id/email',auth, newUser.setUserEmail);

//Get user phone
router.get('/users/:id/phone',auth, newUser.getUserPhone);

//set user phone
router.put('/users/:id/phone',auth, newUser.setUserPhone);

//get user age
router.get('/users/:id/age',auth, newUser.getUserAge);

//set user age
router.put('/users/:id/age',auth, newUser.setUserAge);

//set user status
router.put('/users/:id/status',auth, newUser.setUserStatus);

//get user status
router.get('/users/:id/status',auth, newUser.getUserStatus);

//set user level
router.put('/users/:id/level',auth, newUser.setUserLevel);

//get user level
router.get('/users/:id/level',auth, newUser.getUserLevel);

//get user gender
router.get('/users/:id/gender',auth, newUser.getUserGender);

//set user gender
router.put('/users/:id/gender',auth, newUser.setUserGender);

//set user address
router.put('/users/:id/address',auth, newUser.setUserAddress);

//get user address
router.get('/users/:id/address',auth, newUser.getUserAddress);

//get active users
router.get('/users/status/active',auth, newUser.getActiveUsers);

//get inactive users
router.get('/users/status/inactive',auth, newUser.getInActiveUsers);

//get non admin users
router.get('/users/level/intern',auth, newUser.getInternUsers);

//get mentor users
router.get('/users/level/mentor',auth, newUser.getMentorUsers);

//Get Avatar
router.get('/users/:id/avatar',auth, newUser.getUserAvatar);

//Set Avatar
router.put('/users/:id/avatar',auth, upload.single('avatar'), newUser.setUserAvatar);

//Delete Avatar
router.delete('/users/:id/avatar',auth, newUser.removeUserAvatar);

//Add Companies
router.post('/companies/:id/team', auth, company.setUserTeamName);


module.exports= router;


Solution

  • It looks like in your logout function, the way your attempting to "logout" the user is setting req.session to null.

    As you've figured out this doesn't act how you've expected. The correct way to logout a user would be calling req.session.destroy() usually accompanied by a redirect back to the login page:

    return res.redirect("/login");
    

    This will completely remove or, destroy the session and log the user out.