What am I missing about express sessions and cookies?

与世无争的帅哥 提交于 2020-08-22 04:33:49

问题


I've gotten pretty far with express and express-session and express-sql-session. I've got it creating a row in the database for a session when a user logs in. This is how I set it:

//login route handler
this.bcrypt.compare(password, row.hashed, function(err, passwordsMatch) {
    if (passwordsMatch === true) {
        console.log("user now logged in");
        req.session.user = row;
        req.session.success = 'User successfully logged in';
        res.send(row);
        res.end();
    }
});

Hunky dory! I can hop into my session table and get the row from the database. Here it is:

{"cookie":{"originalMaxAge":600000,"expires":"2015-08-24T23:16:20.079Z","httpOnly":false,"path":"/"},

"user":{"userID":24,"userName":"g","email":"g","joinDate":"2015-08-24T07:15:33.000Z"},"success":"User successfully logged in"}

Notice that you can see the custom use object is set. However, on the next request to get some data, I check for the user object on the session:

// some other route called after login. 
if (!req.session.user) {
    console.log('user not authorized' + JSON.stringify(req.session));
    res.send('not authorized');
    return;
}

but that logs an (apparently) empty session.

user not authorized{"cookie":{"originalMaxAge":600000,"expires":"2015-08-24T23:27:13.455Z","httpOnly":false,"path":"/"}}

Going into the browser, I also see no cookie is set in the resources panel. Shouldn't this be automatically generated with express 4 and session? The docs say you do not need expressCookie() with express 4 anymore. How do I get the correct session on subsequent requests?

Also, if I login again, it just creates a duplicate row in the sessions table. How do I properly set a cookie in the response to make this work for the next request?

Here's my session config if it helps:

// at the beginning of my node server 

import express = require('express');
import bodyParser = require('body-parser');
import Q = require('q');
import mysql = require('mysql');
var app = express();

import bcrypt = require('bcrypt');

import userModule = require('./userModule')
var UserRepository = new userModule.UserNamespace.UserRepository(connectToMySQL, bcrypt, Q );

import session = require('express-session');
var SessionStore = require('express-sql-session')(session);

app.use(function (req, res, next) {
    res.header("Access-Control-Allow-Origin", "*");
    res.header('Access-Control-Allow-Credentials', 'true');
    res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
    next();
});

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


var storeOptions = {
    client: 'mysql',
    connection: {
        host:SQLHOST,
        port:SQLPORT,
        user:SQLUSER,
        password: SQLPASS,
        database: SQLDB
    },
    table: SESSION_TABLE,
    expires: 365 * 24 * 60 * 60 * 1000
};

var sessionStore = new SessionStore( storeOptions );

app.use(session({
    secret: 'meeogog',
    resave: false,
    saveUninitialized: false,
    cookie: { maxAge: 600000,httpOnly: false },
    store: sessionStore
}));

... 

app.post('/users/login/', function (req, res) {
    UserRepository.loginHashed(req, res);
});

..and then more routes, and so forth

回答1:


Right after i bountied this i discovered that it was a combination of using localhost and not setting withCredentials on the xhr request. The localhost is what tripped me up you have to use the fully qualified 127.0.0.1 and to add to the headache, the http files are served on a different port, so had to change the wildcard to reflect that.

so...

//where the server runs on 127.0.0.1:3000 but the http runs from :9000
app.use(session({
    name:'some_session',
    secret: 'lalala',
    resave: true,
    saveUninitialized: false,
    cookie: { maxAge: 365 * 24 * 60 * 60 * 1000,httpOnly: false , domain:'127.0.0.1:9000'},
    store: sessionStore
}));


res.header("Access-Control-Allow-Origin", "http://127.0.0.1:9000");

//important
$http request (angular): useCredentials: true



回答2:


I used to have this issues.

ps: All the following code is provided by:

MEAN.JS

just started to use passport: http://passportjs.org/

"passport": "~0.2.0",
"passport-facebook": "~1.0.2",
"passport-github": "~0.1.5",
"passport-google-oauth": "~0.1.5",
"passport-linkedin": "~0.1.3",
"passport-local": "~1.0.0",
"passport-twitter": "~1.0.2",

basically I just do: express.js

// CookieParser should be above session
app.use(cookieParser());

// Express MongoDB session storage
app.use(session({
    saveUninitialized: true,
    resave: true,
    secret: config.sessionSecret,
    store: new mongoStore({
        db: db.connection.db,
        collection: config.sessionCollection
    })
}));

app.use( function (req, res, next) {
    if ( req.method === 'POST' && (req.url === '/auth/signin'||req.url === '/auth/login') ) {
      if ( req.body.rememberme ) {
        req.session.cookie.maxAge = 2592000000; // 30*24*60*60*1000 Rememeber 'me' for 30 days
      } else {
        req.session.cookie.expires = false;
      }
    }
    next();
  });

// use passport session
app.use(passport.initialize());
app.use(passport.session());

create a passport.js

'use strict';

/**
 * Module dependencies.
  */
var passport = require('passport'),
      User = require('mongoose').model('User'),
      path = require('path'),
      config = require('./config');

   /**
   * Module init function.
   */
module.exports = function() {
     // Serialize sessions
     passport.serializeUser(function(user, done) {
            done(null, user.id);
      });

// Deserialize sessions
passport.deserializeUser(function(id, done) {
    User.findOne({
        _id: id
    }, '-salt -password', function(err, user) {
        done(err, user);
    });
});

// Initialize strategies
config.getGlobbedFiles('./config/strategies/**/*.js').forEach(function(strategy) {
    require(path.resolve(strategy))();
});
 };

inside of strategies folder I did those files:

locals.js

 `
'use strict';

/**
 * Module dependencies.
 */
var passport = require('passport'),
    LocalStrategy = require('passport-local').Strategy,
    User = require('mongoose').model('User');

module.exports = function() {
    // Use local strategy
    passport.use(new LocalStrategy({
            usernameField: 'email',
            passwordField: 'password'
        },
        function(email, password, done) {
            User.findOne({
                email: email
            }).select('-__v -notes -tags').exec(function(err, user) {
                if (err) {
                    return done(err);
                }
                if (!user) {
                    return done(null, false, {
                        message: 'Unknown user or invalid password'
                    });
                }
                if (!user.authenticate(password)) {
                    return done(null, false, {
                        message: 'Unknown user or invalid password'
                    });
                }
                user.password = undefined;
                user.salt = undefined;
                user.notes = undefined;
                user.tags = [];
                return done(null, user);
            });
        }
    ));
};

and finally to login I just do this:

user.auth.js

/**
 * Signin after passport authentication
 */
exports.signin = function(req, res, next) {
    console.log(req.body);
    passport.authenticate('local', function(err, user, info) {
        if (err || !user) {
            res.status(400).send(info);
        } else {
            // Remove sensitive data before login
            user.password = undefined;
            user.salt = undefined;
            user.notes = undefined;
            user.tags = [];
            user.resetPasswordToken = undefined;
            req.login(user, function(err) {
                if (err) {
                    res.status(400).send(err);
                } else {
                    res.json(user);
                }
            });
        }
    })(req, res, next);
};


来源:https://stackoverflow.com/questions/32193283/what-am-i-missing-about-express-sessions-and-cookies

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!