My express V4 app doesn't give me the correct value of the sessions instead just returns undefined. My app was structured and built using express-generator and this is my app.js file.
var express = require('express'),
path = require('path'),
bodyParser = require('body-parser'),
routes = require('./routes/index'),
app = express(),
compression = require('compression'),
session = require('express-session');
// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'ejs');
app.set('view cache', true);
app.enable('trust proxy');
app.use(session({
secret: "Share3na Network!195",
resave: true,
saveUninitialized: true,
cookie: { secure: true, httpOnly: true }
}));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(compression());
app.use(express.static(path.join(__dirname, 'public')));
app.use('/', routes);
And these are the routes the take the session value and send it back.
router.get('/getmask', function(req,res){
res.send(req.session.mask);
});
//GET the mask during event body load
router.get('/sendmask', function(req,res){
req.session.mask = striptags(emojiStrip(req.query.m));
});
In another route when I append the requests' IP address with the session value: req.ip() + req.session.mask, what gets saved in the database is "123.456.789undefined"
You need to save the session values after modification. The documentation for the same can be seen in the README of the package.
//GET the mask during event body load
router.get('/sendmask', function(req,res){
req.session.mask = striptags(emojiStrip(req.query.m));
req.session.save();
});
Related
I want to render app.use('/', callback function) before rendering the static files from public folder.
Basically I am doing the authentication before accessing the website, so once it gets authenticated it should load the index.html (static file) from the public folder.
How should i do it?
I am using W3ID from IBM to authenticate the site.
const express = require('express');
const session = require('express-session');
const passport = require('passport');
const WebAppStrategy = require("ibmcloud-appid").WebAppStrategy;
const CALLBACK_URL = "public/index.html";
var path = require('path');
var bodyParser = require('body-parser');
var port = process.env.VCAP_APP_PORT || 8080;
var mongoose = require('mongoose');
//var MongoStore = require('connect-mongo')(session);
const app = express();
// mongodb connection
mongoose.connect("mongodb://admin:admin123#ds261430.mlab.com:61430/events");
var db = mongoose.connection;
// mongo error
db.on('error', console.error.bind(console, 'connection error:'));
// parse incoming requests
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(express.static(path.join(__dirname, 'public')));
app.set('views', path.join(__dirname, 'views'));
// Set view engine as EJS
app.engine('html', require('ejs').renderFile);
app.set('view engine', 'html');
// include routes
app.use(session({
secret: "123456",
resave: true,
saveUninitialized: true
}));
app.use(passport.initialize());
app.use(passport.session());
passport.use(new WebAppStrategy({
tenantId: "73585f35-8d9c-4f6f-9ab2-d07ca0c1d371",
clientId: "863fce57-a717-4586-b8a2-0bf221ef4e68",
secret: "MzkxMTMxMWMtNmYxNi00ZjNhLWFiNzctZjFlM2NkMDM1ZTkz",
oauthServerUrl: "https://appid-oauth.eu-gb.bluemix.net/oauth/v3/73585f35-8d9c-4f6f-9ab2-d07ca0c1d371",
redirectUri: "https://csi.eu-gb.mybluemix.net/" + CALLBACK_URL
}));
passport.serializeUser(function(user, cb) {
cb(null, user);
});
passport.deserializeUser(function(obj, cb) {
cb(null, obj);
});
app.get(CALLBACK_URL, passport.authenticate(WebAppStrategy.STRATEGY_NAME));
app.use('/',passport.authenticate(WebAppStrategy.STRATEGY_NAME), function(req, res) {`enter code here`
// do your authentication
});
// listen on port 8080
app.listen(port);
You can do this by just putting your app.use('/',...) above the app.use('/',express.static('...')).
Or
You can do this by passing option {index:false} to express.static like
app.use('/',express.static('path here',{index:false}));
This option will set express.static to not send the index.html by default.
I'm getting stuck with connect-flash , all flash messages doesn't load on the page unless I refresh for a couple of times I'm not sure why.
I created a small project just to test connect-flash and it's the same result, please check the code below:
App.js code:
const express = require('express');
const path = require('path');
const favicon = require('serve-favicon');
const logger = require('morgan');
const cookieParser = require('cookie-parser');
const bodyParser = require('body-parser');
const session = require('express-session');
const flash = require('connect-flash');
const app = express();
// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'hbs');
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));
app.use(session({
secret: 'keyboard cat',
resave: false,
saveUninitialized: true
}));
//using flash
app.use(flash());
app.use(function(req, res, next){
res.locals.success = req.flash('success');
res.locals.error = req.flash('error');
next();
});
//flash route
app.get('/flash', (req, res) =>{
req.flash("success", "CONNECT FLASH TEST");
res.render('flash');
});
const port = process.env.PORT || 5000;
app.listen(port, () =>{
console.log(`App has started on port ${port}`);
})
Here's the code for the flash.hbs page to render the flash message:
<h1>Flash page</h1>
{{#if success}}
<h2>{{success}}</h2>
{{/if}}
Thanks so much in advanced, any help would be highly appreciated guys.
Do they render after just one refresh? That's how they are supposed to work.
"Flash messages" are used to carry a message over to the next request, and most of the time the only reason is the post-request-get pattern. If you just want to show a message to the user on the same page, while not doing a redirect, you don't need a library for it. Just pass the message to the template as data.
I was halfway through rolling my own new version of req.flash, when I was looking through the docs of express-session and came across this gem:
Note Since version 1.5.0, the cookie-parser middleware no longer needs to be used for this module to work. This module now directly reads and writes cookies on req/res. Using cookie-parser may result in issues if the secret is not the same between this module and cookie-parser.
And lo, I had these lines:
app.use(require('cookie-parser')())
const session = require('express-session')
const MongoStore = require('connect-mongo')(session)
app.use(session({
secret: process.env.SESSION_STORE_SECRET,
store: new MongoStore({mongooseConnection: mongoose.connection}),
maxAge: 10*365*24*60*60*1000, // set to 10 years
resave: false,
saveUninitialized: false
}))
Once I changed the cookie-parser line to:
app.use(require('cookie-parser')(process.env.SESSION_STORE_SECRET))`
it worked exactly as expected!
(For some people, the answer will be to remove cookie-parser altogether.)
Express-session is creating a new session (new sessionID) for new request. And it happens intermittently, for example sometimes for first 3-4 hits it will work fine and keep using same existing session and on 4th hit it will create a new one, Sometimes it will create new session on first request itself.
Also this Issue comes on my hosted website. It works fine on localhost.
Things that i have already tried and are not working..
Express session is created after static file routes.
Express session secret and cookieParser secret are set to same.
Using app.use(favicon(path.join(__dirname, 'public', 'favicon.ico'))); for favicon.
Setting very high value for max-age field while creating cookie.
Below is my app.js snippet -
var passport = require('passport');
var expressSession = require('express-session');
var app = express();
app.engine('hbs', hbs.express4({
partialsDir: __dirname + '/views/partials'
}));
app.set('view engine', 'hbs');
app.set('views', path.join(__dirname, 'views'));
app.use(favicon(path.join(__dirname, 'public', 'favicon.ico')));
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(express.static(path.join(__dirname, 'public')));
var flash = require('connect-flash');
app.use(flash());
var initPassport = require('./passport/init');
initPassport(passport);
//app.use(bodyParser.urlencoded());
app.use(cookieParser('mysecret'));
app.use(expressSession({ secret: 'mysecret', name:'user', cookie: {maxAge: 60000000}}));
app.use(passport.initialize());
app.use(passport.session());
Any kind of help would be greatly appreciated. Thanks.
why don't you use MongoStore to store session data? may be that will solve your problem.
app.use(session({
secret: 'mysecret',
resave: false,
saveUninitialized: false,
expires: new Date(Date.now() + (60 * 60 * 24 * 7 * 1000)),
cookie: { } ,
store: new MongoStore({mongooseConnection: mongoose.connection})
}));
For those landing here for a similar multi session creation, I solved my issue by setting this flag in the session middleware to false. It saves your cookie in DB only when it has been updated with some additional data like an email for example. `
saveUninitialized: false
I'm writing a Node js application which handles multipart form data and so I'm using multer for the purpose.
The problem is that req.body is always undefined.
Here is my code:
var app = express();
var http = require('http').createServer(app);
//All environments
app.set('port', process.env.PORT || config.ports.HTTP_PORT);
app.set('views', config.folders.views);
app.set('view engine', 'ejs');
//Express 4 dependencies
app.use(morgan('dev'));
app.use(multer({ dest: config.folders.uploads}))
app.use(cookieParser()); //Parser for cookie session
app.use(session({ secret: 'secret' }));
app.use(passport.initialize()); //Init passport
app.use(passport.session()); //Persistent login sessions
app.use(flash()); //Flash messages
//Public folder
app.use(express.static(config.folders.public));
require('./auth')(passport); //Add auth methods to passport
require('./routes')(app, passport); //Add routes
app.post('/test', function(req, res) {
console.log(req.body.test); //req.body always undefined
});
What could be the problem?
EDIT:
Now req.body is filled with data, but the req.files property is still undefined
add bodyParser with this code :
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({
extended: true
}));
HTML forms need to have the enctype attribute set appropriately in order for files to be sent. Example:
<form method="POST" action="/foo" enctype="multipart/form-data">
Editing your original code:
You have to install Multer Multer Docs
npm i multer -S
const app = express();
const http = require('http').createServer(app);
const multer = require('multer'); // added, wasn't in your original code.
//All environments
app.set('port', process.env.PORT || config.ports.HTTP_PORT);
app.set('views', config.folders.views);
app.set('view engine', 'ejs');
//Express 4 dependencies
app.use(morgan('dev'));
// newly added
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({
extended: true
}));
app.use(multer({ dest: config.folders.uploads}).single('file')) // added the single() method
app.use(cookieParser()); //Parser for cookie session
app.use(session({ secret: 'secret' }));
app.use(passport.initialize()); //Init passport
app.use(passport.session()); //Persistent login sessions
app.use(flash()); //Flash messages
//Public folder
app.use(express.static(config.folders.public));
require('./auth')(passport); //Add auth methods to passport
require('./routes')(app, passport); //Add routes
Testing the code:
app.post('/test', (req, res) => {
console.log(req.body.test); //req.body always undefined
console.log(req.file); // added this, it should work fine now.
});
In my understanding, the way to serve views is to do the following:
app.set('view engine', 'ejs'); // or jade or whatever
app.set('views', __dirname + '/views'); // specify where to find the view files e.g. index.ejs
app.get("/", function(req, res) { res.render('index') });
However, when I check the code here https://github.com/jedireza/drywall/ , which is a boilerplate for node user management, I don't see any routes defined in app.js. But it works fine and if I type the url /signup in browser it will render signup.jade.
Which part, or which middleware is doing the magic of routing?
app.js content:
'use strict';
//dependencies
var config = require('./config'),
express = require('express'),
cookieParser = require('cookie-parser'),
bodyParser = require('body-parser'),
session = require('express-session'),
mongoStore = require('connect-mongo')(session),
http = require('http'),
path = require('path'),
passport = require('passport'),
mongoose = require('mongoose'),
helmet = require('helmet'),
csrf = require('csurf');
//create express app
var app = express();
//keep reference to config
app.config = config;
//setup the web server
app.server = http.createServer(app);
//setup mongoose
app.db = mongoose.createConnection(config.mongodb.uri);
app.db.on('error', console.error.bind(console, 'mongoose connection error: '));
app.db.once('open', function () {
//and... we have a data store
});
//config data models
require('./models')(app, mongoose);
//settings
app.disable('x-powered-by');
app.set('port', config.port);
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'jade');
//middleware
app.use(require('morgan')('dev'));
app.use(require('compression')());
app.use(require('serve-static')(path.join(__dirname, 'public')));
app.use(require('method-override')());
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
app.use(cookieParser(config.cryptoKey));
app.use(session({
resave: true,
saveUninitialized: true,
secret: config.cryptoKey,
store: new mongoStore({ url: config.mongodb.uri })
}));
app.use(passport.initialize());
app.use(passport.session());
app.use(csrf({ cookie: { signed: true } }));
helmet(app);
//response locals
app.use(function(req, res, next) {
res.cookie('_csrfToken', req.csrfToken());
res.locals.user = {};
res.locals.user.defaultReturnUrl = req.user && req.user.defaultReturnUrl();
res.locals.user.username = req.user && req.user.username;
next();
});
//global locals
app.locals.projectName = app.config.projectName;
app.locals.copyrightYear = new Date().getFullYear();
app.locals.copyrightName = app.config.companyName;
app.locals.cacheBreaker = 'br34k-01';
//setup passport
require('./passport')(app, passport);
//setup routes
require('./routes')(app, passport);
//custom (friendly) error handler
app.use(require('./views/http/index').http500);
//setup utilities
app.utility = {};
app.utility.sendmail = require('./util/sendmail');
app.utility.slugify = require('./util/slugify');
app.utility.workflow = require('./util/workflow');
//listen up
app.server.listen(app.config.port, function(){
//and... we're live
});
The routes are being added here:
//setup routes
require('./routes')(app, passport);