Постоянный логин перестает работать с Node.js, Express, PassportJS, Connect-Mongo

В какой-то момент постоянный логин с моим приложением перестает работать, и я понятия не имею, почему. Дело в том, что даже когда я просто обновляю страницу, приложение, пользователь выходит из системы. Я создал это приложение вне лесов, предоставленных MEAN.js, поэтому у меня возникли проблемы с поиском проблемы. Могу ли я, пожалуйста, помочь отладить это? Любая помощь была оценена.

Вот мой экспресс файл

var fs = require('fs'),
    http = require('http'),
    https = require('https'),
    express = require('express'),
    morgan = require('morgan'),
    bodyParser = require('body-parser'),
    session = require('express-session'),
    compress = require('compression'),
    acl = require('acl'),
    methodOverride = require('method-override'),
    cookieParser = require('cookie-parser'),
    helmet = require('helmet'),
    passport = require('passport'),
    mongoStore = require('connect-mongo')({
        session: session
    }),
    flash = require('connect-flash'),
    config = require('./config'),
    consolidate = require('consolidate'),
    path = require('path');

module.exports = function(db) {
    // Initialize express app
    var app = express();

    // Globbing model files
    config.getGlobbedFiles('./app/models/**/*.js').forEach(function(modelPath) {
        require(path.resolve(modelPath));
    });

    /**
     * Configure the modules ACL policies
     */
    // Globbing policy files
    config.getGlobbedFiles('app/policies/*.js').forEach(function(policyPath) {
        require(path.resolve(policyPath)).invokeRolesPolicies();
    });

    // Setting application local variables
    app.locals.title = config.app.title;
    app.locals.description = config.app.description;
    app.locals.keywords = config.app.keywords;
    app.locals.facebookAppId = config.facebook.clientID;
    app.locals.jsFiles = config.getJavaScriptAssets();
    app.locals.cssFiles = config.getCSSAssets();

    // Passing the request url to environment locals
    app.use(function(req, res, next) {
        res.locals.url = req.protocol + '://' + req.headers.host + req.url;
        next();
    });

    // Should be placed before express.static
    app.use(compress({
        filter: function(req, res) {
            return (/json|text|javascript|css/).test(res.getHeader('Content-Type'));
        },
        level: 9
    }));

    // Showing stack errors
    app.set('showStackError', true);

    // Set swig as the template engine
    app.engine('server.view.html', consolidate[config.templateEngine]);

    // Set views path and view engine
    app.set('view engine', 'server.view.html');
    app.set('views', './app/views');

    // Environment dependent middleware
    if (process.env.NODE_ENV === 'development') {
        // Enable logger (morgan)
        app.use(morgan('dev'));

        // Disable views cache
        app.set('view cache', false);
    } else if (process.env.NODE_ENV === 'production') {
        app.locals.cache = 'memory';
    }

    // Request body parsing middleware should be above methodOverride
    app.use(bodyParser.urlencoded({
        extended: true
    }));
    app.use(bodyParser.json());
    app.use(methodOverride());

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

    // Express MongoDB session storage
    app.use(session({
        saveUninitialized: true,
        resave: true,
        secret: config.sessionSecret,
        cookie: {
            maxAge: config.sessionCookie.maxAge,
            httpOnly: config.sessionCookie.httpOnly,
            secure: config.sessionCookie.secure && config.secure.ssl
        },
        key: config.sessionKey,
        store: new mongoStore({
            db: db.connection.db,
            collection: config.sessionCollection
        })
    }));

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

    // connect flash for flash messages
    app.use(flash());

    // Use helmet to secure Express headers
    app.use(helmet.xframe());
    app.use(helmet.xssFilter());
    app.use(helmet.nosniff());
    app.use(helmet.ienoopen());
    app.disable('x-powered-by');

    // Setting the app router and static folder
    app.use(express.static(path.resolve('./public')));

    // Globbing routing files
    config.getGlobbedFiles('./app/routes/**/*.js').forEach(function(routePath) {
        require(path.resolve(routePath))(app);
    });

    // Assume 'not found' in the error msgs is a 404. this is somewhat silly, but valid, you can do whatever you like, set properties, use instanceof etc.
    app.use(function(err, req, res, next) {
        // If the error object doesn't exists
        if (!err) return next();

        // Log it
        console.error(err.stack);

        // Error page
        res.status(500).render('500', {
            error: err.stack
        });
    });

    // Assume 404 since no middleware responded
    app.use(function(req, res) {
        res.status(404).render('404', {
            url: req.originalUrl,
            error: 'Not Found'
        });
    });

    if (process.env.NODE_ENV === 'secure') {
        // Log SSL usage
        console.log('Securely using https protocol');

        // Load SSL key and certificate
        var privateKey = fs.readFileSync('./config/sslcerts/key.pem', 'utf8');
        var certificate = fs.readFileSync('./config/sslcerts/cert.pem', 'utf8');

        // Create HTTPS Server
        var httpsServer = https.createServer({
            key: privateKey,
            cert: certificate
        }, app);

        // Return HTTPS server instance
        return httpsServer;
    }

    // Return Express server instance
    return app;
};

Результат записи в консоли объекта конфигурации

{ root: '/Users/yako/Developer/ronny/trunk/meanjs',
  app: { title: 'Dyad Medical - Development Environment' },
  sessionCookie: { maxAge: 86400000, httpOnly: true, secure: false },
  port: 3000,
  templateEngine: 'swig',
  sessionSecret: 'XXXXXXXXXX',
  sessionCollection: 'sessions',
  sessionKey: 'sessionId',
  assets: 
   { lib: { css: [Object], js: [Object] },
     css: [ 'public/modules/**/css/*.css' ],
     js: 
      [ 'public/config.js',
        'public/application.js',
        'public/modules/*/*.js',
        'public/modules/*/*[!tests]*/*.js' ],
     tests: 
      [ 'public/lib/angular-mocks/angular-mocks.js',
        'public/modules/*/tests/*.js' ] },
  db: 'mongodb://localhost/medical-dyad-dev',
  facebook: 
   { clientID: 'APP_ID',
     clientSecret: 'APP_SECRET',
     callbackURL: '/auth/facebook/callback' },
  twitter: 
   { clientID: 'CONSUMER_KEY',
     clientSecret: 'CONSUMER_SECRET',
     callbackURL: '/auth/twitter/callback' },
  google: 
   { clientID: 'APP_ID',
     clientSecret: 'APP_SECRET',
     callbackURL: '/auth/google/callback' },
  linkedin: 
   { clientID: 'APP_ID',
     clientSecret: 'APP_SECRET',
     callbackURL: '/auth/linkedin/callback' },
  github: 
   { clientID: 'APP_ID',
     clientSecret: 'APP_SECRET',
     callbackURL: '/auth/github/callback' },
  mailer: 
   { from: 'MAILER_FROM',
     options: { service: 'gmail', auth: [Object] } },
  seedDB: 
   { seed: false,
     options: { logResults: true, seedUser: [Object], seedAdmin: [Object] } },
  getGlobbedFiles: [Function],
  getJavaScriptAssets: [Function],
  getCSSAssets: [Function] }

Ответы

Ответ 1

У вашего приложения есть этот параметр для файлов cookie:

    cookie: {
        maxAge: config.sessionCookie.maxAge,
        httpOnly: config.sessionCookie.httpOnly,
        secure: config.sessionCookie.secure && config.secure.ssl
    },

Так как config.sessionCookie.secure всегда false, тогда строка выше всегда будет считаться ложной. Кроме того, нет никакой настройки для свойства config.secure.ssl

Если вы используете HTTPS, вы должны убедиться, что для параметра cookie.secure установлено значение true. Один из способов исправить это - получить значение SSL выше в коде следующим образом:

var secureConfig = (process.env.NODE_ENV === 'secure') ? true:false;

И затем используйте это, чтобы настроить строку конфигурации cookie на следующее:

    cookie: {
        maxAge: config.sessionCookie.maxAge,
        httpOnly: config.sessionCookie.httpOnly,
        secure: secureConfig
    },

Ответ 2

вам нужно сохранить данные сеанса пользователя, когда пользователь успешно войдет в хранилище сеансов/локальное хранилище или global.window, чтобы он стал постоянным даже после обновления пользователем страницы. Оттуда вы всегда можете сравнить клиент sessionId и пользовательский сеанс mongoDb с использованием стандартного HTTP-запроса.