Постоянный логин перестает работать с 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-запроса.