elzoy
elzoy

Reputation: 5445

Nodejs express4 - undefined session

my problem is that my session is undefined as in new layers as even after "if" where the session value was set.

/*******************************************/
/**/  var express         = require('express'),
/**/      cookieParser    = require('cookie-parser'),
/**/      session         = require('express-session'),
/**/      bodyParser      = require('body-parser'),
/**/      ejs             = require('ejs'),
/**/      mysql           = require('mysql'),
/**/      md5             = require('md5');
/*******************************************/

var app = express();
var connection = mysql.createConnection({
  host: 'localhost',
  user: 'root',
  password: '',
  database: 'samurai'
});

connection.connect(function(error) {
  if(error) {
    console.log("There is a problem with connection to the database.");
    return;
  }
    console.log("Connected with a database.");
});

app.use(cookieParser());
app.use(session({
    secret: 'test session',
    resave: false,
    saveUninitialized: true
}));

var sess;

Here my session is undefined (first I go to the '/sign' address):

app.get('/', function(req, res) {
  sess = req.session;
  console.log("sesja = "+sess.login); <--------------- undefined

  if(sess.login) {
    res.render('indexo');
  } else {
    res.render('index');
  }
});


app.post('/sign', function(req, res, next) {
    sess=req.session;

    var query = 'SELECT * FROM ?? where ??=? AND ??=?';
    var table = ["users", "name", req.body.login, "password", md5(req.body.password)];
    query = mysql.format(query, table);
    connection.query(query, function(err, rows) {
      if(err) {
        console.log(err);
        return;
      } else if(rows.length > 0) {
        console.log("You have been sucessfully logged in.");
        sess.login = req.body.login;
        console.log(sess.login); <------------ works fine
      } else {
        console.log("The name or password is incorrect.");
      }
    });
    console.log(sess.login); <---------------- here again undefined
    res.end();
});

The problem is only in sessions case because if I create other global variable next to "var sess;" (for example var test;) and set for the variable a value in the "if" in '/sign" layer, then the "test" would be visible in the other layers and after that "if".

The final question: Why the session.login is invisible after the "if" and in other layer? How to set it properly? Have you some tips for me with sessions creating?

Thank you guys for your time and help.

Upvotes: 0

Views: 52

Answers (1)

jfriend00
jfriend00

Reputation: 708026

Setting global variables from an http request is an evil thing to do and is fraught with problems. First off, your server can have multiple requests in flight at the same time from different users. Using globals from requests like this means that different requests will "stomp" on each others globals and all sorts of chaos and bugs will ensue.

Stop using globals at all for session information. If you need to communicate session info to other functions, then pass it to them as function arguments.

And, secondly you MUST understand how async operations work in node.js to have any chance of programming successfully in node.js. You are making several mistakes with your asynchronous programming and that's one main reason why variables aren't set where you think they should be.

In this code:

app.post('/sign', function(req, res, next) {
    sess=req.session;

    var query = 'SELECT * FROM ?? where ??=? AND ??=?';
    var table = ["users", "name", req.body.login, "password", md5(req.body.password)];
    query = mysql.format(query, table);
    connection.query(query, function(err, rows) {
      if(err) {
        console.log(err);
        return;
      } else if(rows.length > 0) {
        console.log("You have been sucessfully logged in.");
        sess.login = req.body.login;
        console.log(sess.login); <------------ works fine
      } else {
        console.log("The name or password is incorrect.");
      }
    });
    // this is executed BEFORE the connection.query() callback is called
    console.log(sess.login); <---------------- here again undefined
    res.end();
});

connection.query() is asynchronous. T'hat means that it calls its callback sometime in the future. Thus your console.log(sess.login); at the end of your request is happening BEFORE the callback has ever been called.

You aren't specific about exactly what you want to happen in all the cases in your query, but here's an outline for how the code could work:

app.post('/sign', function(req, res, next) {
    var query = 'SELECT * FROM ?? where ??=? AND ??=?';
    var table = ["users", "name", req.body.login, "password", md5(req.body.password)];
    query = mysql.format(query, table);
    connection.query(query, function(err, rows) {
      if(err) {
        console.log(err);
        res.end("Query error");
      } else if(rows.length > 0) {
        res.end("Logged in successfully");
      } else {
        res.end("The name or password is incorrect.");
      }
    });
});

You may find this general answer on asynchronous responses useful: How do I return the response from an asynchronous call?

Upvotes: 1

Related Questions