Search code examples
node.jssession-cookiesexpress-session

Session data could not be access on loading but fine when reload the same page in node.js


I'm a beginner playing with sessions authentication in node.js. It almost work fine at my level that,

  • session got initialized when user logged in
  • session got stored inside database on logged in and deleted when logged out.
  • session expired within a period i want.
  • problem: I wanna render user email through res.render('admin',{user})in view but it disappear on loading(logged in) and appeared as soon as i reload the same view page. It seems like condition if(req.session.userEmail) in routes/pages.js is false when loading but true when reload the same page. In short on loading else part in routes/pages.js is viewed only but when reload stuff under if condition is viewed at client side. Why it is appeared on reload not on loading?? please help.
  • routes/pages.js

const express= require('express');
const { removeAllListeners } = require('nodemon');
const router=express.Router();

router.get('/views/admin', (req, res)=>{
  console.log(req.session);
  if(req.session.userEmail){

      res.render('admin', {user});
      
  }else{
    res.send('<p>Session Expired. Click <a href="/views/login">here</a> to login</p>');   
  }  
});
**

  • log on load

**

Session {
  cookie: {
    path: '/',
    _expires: null,
    originalMaxAge: null,
    httpOnly: true,
    sameSite: true
  }
}

  • log on reload

Session {
  cookie: {
    path: '/',
    _expires: null,
    originalMaxAge: null,
    httpOnly: true,
    sameSite: true
  },
  userEmail: 'pdm@gmail.com'
}

  • routes/auth.js

const express= require('express');
const authController= require('../controller/auth');
const router= express.Router();
router.post('/signup',authController.signup);
router.post('/login',authController.login);
router.post('/logout',authController.logout);
module.exports=router;

`

  • controller/auth.js

const router = require('../routes/auth');
const bycrypt= require('bcryptjs');

exports.login= (req, res)=>{

    const {email,password}=req.body;

    myPool.query('SELECT*FROM userinfo WHERE uemail=?' ,[email],(err,rows,fields)=>{
        if(err){
            console.log(err);
        }else if(rows.length>0){
            bycrypt.compare(password,(rows[0].upwd),(err,success)=>{
                if(err){
                    console.log(err);
                }else{
                    console.log(success);//print fine
                    if(success==false||rows[0].uemail!==email){
                        return res.render('login',{
                            message:'Incorrect Password'
                        });
                    }else {
                        var sessUser=req.session;
                        sessUser.userEmail=email;
                        console.log(sessUser.userEmail)//print fine
                        if(sessUser.userEmail){
                            res.redirect('../views/admin');
                        }
                       }  
                }
            })
    }else{
        return res.render('login',{
            message:'This Email does not exist'
        })
    }
            
});
}


  • log

true
pdm@gmail.com

index.js

const express = require('express');
const session = require('express-session');
const mySqlStore = require('express-mysql-session')(session);
const mysql = require('mysql');
const bodyParser = require('body-parser');
const path = require('path');
const dotenv = require('dotenv');
const {
  request
} = require('https');
const app = express();
app.use((req, res, next) => { console.log(req.url, req.session && req.session.userEmail); next();})//it print current 'url' and 'undefined'
dotenv.config({
  path: './.env'
});
const options = {
  connectionLimit: 10,
  host: 'localhost',
  user: 'root',
  password: 'password',
  database: 'logindb',
  createDatabaseTable: true
}
myPool = mysql.createPool(options);
const sessionStore = new mySqlStore(options, myPool);
app.use(session({
  name: process.env.SESS_NAME,
  secret: 'my secret',
  saveUninitialized: false,
  resave: true,
  store: sessionStore,
  cookie: {
    maxAge: 10 * 60 * 1000,
    httpOnly: true,
    sameSite: true
  }
}));
const publicDirectory = path.join(__dirname, './public');
app.use(express.static(publicDirectory));
app.use(express.urlencoded({
  extended: false
}));
app.use(express.json());
app.set('view engine', 'hbs');
app.use('/', require('./routes/pages'));
app.use('/auth', require('./routes/auth'));
app.listen(8084, () => console.log('Server is running at port:8084'));
exports.store = sessionStore;


  • All logs

Server is running at port:8084
---before login---
/views/login undefined
/style.css undefined

---On login---
/auth/login undefined
/views/admin undefined

---On reload after login---
/views/admin undefined
/style.css undefined

---On logout---
/auth/logout undefined
/views/login undefined
/style.css undefined


Solution

  • It is not obvious what is going on. It could be a timing issue where the redirect after login is arriving back on your server BEFORE the session data gets successfully saved in your database. You can eliminate that possibility by changing this:

    var sessUser=req.session;
    sessUser.userEmail=email;
    console.log(sessUser.userEmail)//print fine
    if(sessUser.userEmail){
        res.redirect('../views/admin');
    }
    

    to this:

    var sessUser = req.session;
    sessUser.userEmail = email;
    console.log(sessUser.userEmail);
    req.session.save((err) => {
        if (err) {
            console.log("session save error", err);
            res.sendStatus(500);
        } else {
            res.redirect('../views/admin');
        }
    });