Monday 5 June 2017

Remain session between cross domain ajax requests with ajax to node.js server

I have server side app that sitting in Heroku and client side app that sitting in Go-Daddy with SSL. The server side based Node.js while the client side is a simple JavaScript. I'm trying to manage sessions in the server- at first, I'm calling '/login' route with POST method and saving the user data in the session. In the next call, the session doesn't contain the user data.

The code:

server.js

    var express = require('express');
    var app = express();
    var bodyParser = require('body-parser');
    var cors = require('cors');
    var sessions = require('./sessions.js');
    var db = require('./database');
    var consts = require('./consts');

    app.set('port', consts.port);

    app.use(cors());
    app.use(bodyParser.json()); // support json encoded bodies
    app.use(bodyParser.urlencoded({ extended: true })); // support encoded bodies
    app.use(sessions());

    app.use('/', express.static('./public'));
    app.use(function(req, res, next){
        var headerOrigin = (process.env.ENV_VAR == 'development') ? "*" : req.headers.origin;
        res.header('Access-Control-Allow-Credentials', 'true');
        res.header('Access-Control-Allow-Origin',  headerOrigin);
        res.header('Access-Control-Allow-Methods','GET,PUT,POST,DELETE');
        res.header('Access-Control-Allow-Headers', 'X-Requested-With, X-HTTP-Method-Override, Content-Type, Accept');
        app.set('json spaces', 4);
        res.set('Content-Type', "application/json");
        next();
    });
require('./routes')(app);

app.listen(consts.port);

console.log('The server is running on port '+ consts.port);

sessions.js

var express = require('express');
var expressSession  = require('express-session');
var MongoStore = require('connect-mongo')(expressSession);
var consts = require('./consts');

module.exports = function() {
  var session = expressSession({
    secret: 'foo',
    rolling: true,
    saveUninitialized: false,
    resave: true,
    cookie: {
        httpOnly: false,
        secure: false,
        domain: consts.domain,
        maxAge: 24*60*60*1000 //one hour
    },
    store: new MongoStore({url : consts.mongoUrl})
  });

  return session;
};

login function

exports.login = function(req, res){
    var username = req.body.username,
        password = req.body.password;
        sess = req.session;

        // fetch user and test password verification
        User.findOne({ username: username }, function(err, user) {
            if(!user){
                 Message.messageRes(req, res, 404, "error", "User with the username "+username+" isn't exist");
             }else if(err){
                 Message.messageRes(req, res, 500, "error", err);
             } else {
                 user.comparePassword(password, function(err, isMatch) {
                    if (err){
                        Message.messageRes(req, res, 200, "error", err);
                    }else{
                        if(isMatch){
                            sess.isLoggedIn = true;     
                            sess.user = user;
                            sess.save();
                            Message.messageRes(req, res, 200, "success", "User can login"); 
                        } else {
                            sess.isLoggedIn = false;   
                            Message.messageRes(req, res, 200, "error", "wrong password");  
                        }
                    }

                });
             }

        });


};

ajax request

var url = 'https://example.herokuapp.com/';

$.ajax({
   url: url,
   xhrFields: {
      withCredentials: true
   },
   cache: false,
   crossDomain: true,
   dataType: 'json',
   method: "GET",
   success: function(data){
       //.....
        }
    });

After I do login - I can see the cookie in the response header, but when I go to another page and do another request there, It won't recognize the session. The session itself does saved in the mongoDB.



via AvitalG

No comments:

Post a Comment