Search code examples
node.jsmongooseexpress-session

Error with express-session when user login in Node.JS


So basically in this code is only registration and login forms and it worked very well until I added session to it.

The problem is when user registers, it logs in console registered user's info, it is ok, but when user gets back to login page and refreshes page, console logs the information that logged when user registered and also session does not works, I am 100% sure that this is session problem, but I can not configure what it is, here is the code (don't pay attention to 'Friends' model it is for future purposes, and I also tested without that block of code and it worked so problem is not there)

   const http = require('http');
   const express = require('express');
   const socketIO = require('socket.io');
   const bodyParser = require('body-parser');
   const multer = require('multer');
   const consolidate = require('consolidate');
   const session = require('express-session');

  const app = express();
  const server = http.Server(app);
  const io = socketIO(server);
  app.use(session({secret: 'zazagelovidzudzua', resave: false,                               
  saveUninitialized: true}))
  app.engine('html', consolidate.mustache);
  app.set('view engine', 'html');
  app.set('views', __dirname + '/views');

  app.use(bodyParser.json());
  app.use(bodyParser.urlencoded({extended: true}));
  app.use(multer().array());
  app.use(express.static('public'));

  const mongoose = require('mongoose');
  const connectionUri = 'mongodb://localhost/my_database';
  mongoose.Promise = global.Promise;

  mongoose
    .connect(connectionUri, {useNewUrlParser: true})
    .then(() => {
      console.log('Connection to database established');
    })
    .catch(error => {
      console.error('MongoDB connection error:', error.message);
      process.exit(-1);
    });


  const Schema = mongoose.Schema;
  const UserSchema = new Schema({
    username: String,
    password: String,
    email: String,
    friends: [{type: Schema.Types.ObjectId, ref: 'Friends'}]
  });

  const Friend = new Schema({
    name: {type: Schema.Types.ObjectId, ref: 'User'},
    age: Number,
    address: String
  })

  const User = mongoose.model('User', UserSchema);
  const Friends = mongoose.model('Friends', Friend)
    var ses;

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

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

  app.post(
    '/reeg',
    async (req,res) => {
      try {
  const username = req.body.username
  const password = req.body.password
  const email = req.body.email
  const user = await User.create({username, password, email});
  console.log('Created user:', user);
  res.sendFile(__dirname + '\\views\\mainpage.html')
      }
      catch (error) {
        res.status(500).send(error.message);
      }
    });

  app.post('/login', 
    async (req,res) => {
      ses = req.session

  const {username, password} = req.body;
  const user = await User.findOne({username, password}).select('-            
  password').lean();
        if(!user) {
          res.send('User: ' + username +' not registered');
          return;
        }
        ses.user = user
        res.redirect('/dash')
        return res.status(200);




    });

    app.get('/dash',
    async (req,res) =>{

      try{
        if(!ses.user){
        res.status(401).send('login first please!')
        res.status(200)
        res.send('hi' + ses.user.username)
       }
      }

      catch(error){
  console.log(error.message)
      }


  })



  server.listen('8080');

pic when i refresh page after i register image


Solution

  • Your error at

    return res.status(200);
    
    ses.user = user
    

    You send status 200 to user, but you also return, that mean function not run continue, that make ses.user = user is unreachable (on VS Code, that line will be blur, detect it cannot be reachable).

    My hint for you don't create variable ses, because express-session will create session in req for each user, but ses is used common for your server Node.JS, that mean all users use only this var ses. You should use req.session for each request.

    Your code should be:

    const http = require('http');
    const express = require('express');
    const socketIO = require('socket.io');
    const bodyParser = require('body-parser');
    const multer = require('multer');
    const consolidate = require('consolidate');
    const session = require('express-session');
    
    const app = express();
    const server = http.Server(app);
    const io = socketIO(server);
    app.use(session({
        secret: 'zazagelovidzudzua', resave: false,
        saveUninitialized: true
    }))
    app.engine('html', consolidate.mustache);
    app.set('view engine', 'html');
    app.set('views', __dirname + '/views');
    
    app.use(bodyParser.json());
    app.use(bodyParser.urlencoded({ extended: true }));
    app.use(multer().array());
    app.use(express.static('public'));
    
    const mongoose = require('mongoose');
    const connectionUri = 'mongodb://localhost/my_database';
    mongoose.Promise = global.Promise;
    
    mongoose
        .connect(connectionUri, { useNewUrlParser: true })
        .then(() => {
            console.log('Connection to database established');
        })
        .catch(error => {
            console.error('MongoDB connection error:', error.message);
            process.exit(-1);
        });
    
    
    const Schema = mongoose.Schema;
    const UserSchema = new Schema({
        username: String,
        password: String,
        email: String,
        friends: [{ type: Schema.Types.ObjectId, ref: 'Friends' }]
    });
    
    const Friend = new Schema({
        name: { type: Schema.Types.ObjectId, ref: 'User' },
        age: Number,
        address: String
    })
    
    const User = mongoose.model('User', UserSchema);
    const Friends = mongoose.model('Friends', Friend)
    // var ses; // don't create this var
    
    app.get('/', (req, res) => {
        res.render('mainpage');
    });
    
    app.get('/reg', (req, res) => {
        res.render('reg');
    });
    
    app.post(
        '/reeg',
        async (req, res) => {
            try {
                const username = req.body.username
                const password = req.body.password
                const email = req.body.email
                const user = await User.create({ username, password, email });
                console.log('Created user:', user);
                res.sendFile(__dirname + '/views/mainpage.html')
            }
            catch (error) {
                res.status(500).send(error.message);
            }
        });
    
    app.post('/login',
        async (req, res) => {
            ses = req.session
            try {
                const { username, password } = req.body;
                const user = await User.findOne({ username, password }).select('-password').lean();
                if (!user) {
                    res.send('User: ' + username + ' not registered');
                    return;
                }
                // ses.user = user
                req.session.user = user; // assign direct data to session for req
    
                return res.status(200).send('Session ID: ' + req.sessionID);
    
                // ses.user = user // unreachable statement
            }
            catch (error) {
                res.status(500).send(error.message);
            }
        });
    
    app.get('/dash',
        async (req, res) => {
            // if (!ses.user) {
            if (!req.session.user) {
                    res.status(401).send('login first please!')
            }
            res.status(200)
            // res.send('hi' + ses.user.username)
            res.send({
                sessionID: req.sessionID,
                message: 'Hi ' + req.session.user.username
            })
        })
    
    
    server.listen('8080');