持久登录已停止使用Node.js,Express,PassportJS,Connect-Mongo

时间:2016-04-11 09:38:25

标签: javascript node.js mongodb

在某些时候,我的应用程序的持久登录停止了工作,我不明白为什么。问题是,即使我只是刷新页面,应用程序,用户也会被注销。我使用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] }

2 个答案:

答案 0 :(得分:1)

您的应用有以下Cookie设置:

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

由于config.sessionCookie.secure始终为false,因此上述行始终会解析为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
    },

答案 1 :(得分:1)

当用户成功登录会话存储/本地存储或global.window时,您需要保存用户会话数据,因此即使在用户刷新页面后它也会保持持久性。从那里,您始终可以使用标准HTTP请求比较客户端sessionId和mongoDb用户sessionId。