At some point persistent login with my application stopped working and I have no idea why. The thing is that even when I simply refresh the page, the app, the user is logged out. I built this application off of scaffolding provided by MEAN.js, so I'm having trouble locating the problem. Can I please have help debugging this? Any help appreciated.
Heres my express setup file
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] }
Your app has this setting for cookies:
cookie: {
maxAge: config.sessionCookie.maxAge,
httpOnly: config.sessionCookie.httpOnly,
secure: config.sessionCookie.secure && config.secure.ssl
},
Since config.sessionCookie.secure
is always false
, then the line above will always resolve as false. Also, there is no setting anywhere for the property config.secure.ssl
If you are using HTTPS, then you should ensure that cookie.secure
is set to true
. One way to fix it is to get the SSL setting higher up in the code like this:
var secureConfig = (process.env.NODE_ENV === 'secure') ? true:false;
And then use that to set the cookie config line to the following:
cookie: {
maxAge: config.sessionCookie.maxAge,
httpOnly: config.sessionCookie.httpOnly,
secure: secureConfig
},
you need to save the user session data when user successfully login to Session Storage/Local Storage or global.window, so it become persistent even after the user refresh the page. From there you can always compare the client sessionId and mongoDb user sessionId using standard HTTP request.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With