I have a handler for '/', which redirects to /login.html.
However, even though i'm explicitly calling to redirection, the page that is rendered is STILL index.html.
it's pretty lame behaviour, since I'm expecting A and gets B.
How can I solve it?
var app = express();
app.use(express.static('public'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({extended: false}));
app.use(cookieParser());
app.use(session({ secret: 'keyboard cat', resave: false, saveUninitialized: false }));
app.use(passport.initialize());
app.use(passport.session());
MW:
app.use('/', (req, res, next) => {
if (req.user) {
next();
} else {
res.redirect('/login.html');
}
});
app.post('/login',
passport.authenticate('local', {
successRedirect: '/index.html',
failureRedirect: '/login.html'
})
);
Related
app.use(bodyParser.urlencoded({
extended: true
}));
app.use(bodyParser.json());
app.use(express_session({
secret: 'abcdefg',
proxy: true,
resave: true,
saveUninitialized: true,
}));
app.post("/login", function(req, res, next) {
var session = req.session;
session.user = 'dadsvadsvhaha';
});
Here is my code. I have used this previously in the same way. But now its not working, unable to figure it out.
I tried following and works fine for me. It just increments value to request.session.views variable if existing or sets request.session.views = 1
// Use the session middleware
app.use(session({ secret: 'keyboard cat', cookie: { maxAge: 60000 }}))
// Access the session as req.session
app.get('/', function(req, res, next) {
var sess = req.session
if (sess.views) {
sess.views++
res.setHeader('Content-Type', 'text/html')
res.write('<p>views: ' + sess.views + '</p>')
res.write('<p>expires in: ' + (sess.cookie.maxAge / 1000) + 's</p>')
res.end()
} else {
sess.views = 1
res.end('welcome to the session demo. refresh!')
}});
Which version of Node.Js are you using?
var express = require('express')
var parseurl = require('parseurl')
var session = require('express-session')
var app = express()
app.use(session({
secret: 'keyboard cat',
resave: false,
saveUninitialized: true
}))
This is my simple code. However, I want to use session only if the req.url contains /web. Is there a way I can wrap this inside a middleware of my own?
I've tried:
function setSession(req,res,next){
if(req.url.indexOf('/api') != 0){
app.use(session({
secret: 'keyboard cat',
resave: false,
saveUninitialized: true
}));
next();
}else{
next();
}
};
and then
app.use(setSession);
But setting req.session.hello = "world" in my controller gives: TypeError: Cannot set property 'hello' of undefined. Simply put, it doesn't work. Are my arguments wrong in my middleware?
However, I want to use session only if the req.url contains /web. Is there a way I can wrap this inside a middleware of my own?
You certainly can. You can use express.Router to create sub-routes, like this:
var sessionMiddleware = session({
secret: 'keyboard cat',
resave: false,
saveUninitialized: true
});
var webRoutes = express.Router()
.get('/', function(req, res, next) {
res.send('I have a session!');
});
var nonWebRoutes = express.Router()
.get('/', function(req, res, next) {
res.send('No session here');
});
app.use('/web', express.Router()
.use(sessionMiddleware)
.use(webRoutes));
app.use('/nonweb', nonWebRoutes);
Edit:
If however you want to conditionally execute the middleware function, you could do it like this:
app.use(function(req, res, next) {
if (req.url.indexOf('/api') !== 0) {
sessionMiddleware(req, res, next);
} else {
next();
}
});
app.get('/api', function(req, res, next) {
res.send(!!req.session); //false
});
app.get('/web', function(req, res, next) {
res.send(!!req.session); //true
});
But I prefer the sub-route approach because it maps your path route structure to a hierarchy which makes the code easier to read and easier to incorporate other middleware that make use of sessions, like passport.js for example.
app.engine('html', ejs.renderFile)
.set("views", __dirname + '/views')
.use("/public", express.static(__dirname + '/public'));
/*********************************************************************/
app.use(cookieParser());
app.use(session({
store: new RedisStore({
host: "127.0.0.1",
port: "3636"
}),
secret: 'keyboard cat',
resave: false,
saveUninitialized: true
}));
app.use(function(req, res, next) {
var userSession = req.session.userSession;
if (!userSession) {
userSession = req.session.userSession = '';
}
next();
});
/************************************************************************/
server.listen(8080);
app.get('/', function(req, res) {
res.render('index2.html', {
infoUser: req.session.userSession
});
})
.use(function(req, res, next) {
res.redirect('/');
});
console shows me :
TypeError: Cannot read property 'userSession' of undefined.
I'm sure this error is caused by 'RedisStore' object but i don't know why and i don't know how the fixed ?
Have I any mistakes?
help me please !!!
The problem is in your RedisStore config. The port setting should be a number, like this:
app.use(session({
store: new RedisStore({
host: "localhost",
port: 3636
}),
secret: 'keyboard cat',
resave: false,
saveUninitialized: true
}));
If that doesn't fix it you should also make sure 3636 is the correct port. Redis uses 6379 by default.
I am trying to show a protected page /enquete (a page that can only be seen by logged in users) after the /login. I am implementing it using passport-local. I have checked the login function returns a user (req.isAuthorized() is true) and it is actually trying to go to /enquete but when trying to access/enquete somehow the req.isAuthorized() is false. So I cannot access it :(.
I wonder what I am missing here? Is this the right way to do this?
These are parts of my code:
passport.use(new LocalStrategy(function (username, password, done) {
process.nextTick(function() {
model.findByUsername(username, function(err, user) {
if (err) { return done(err); }
if (!user) { return done(null, false, { message: 'Unknown user ' + username }); }
if (user.password != password) { return done(null, false, { message: 'Invalid password' }); }
return done(null, user); // <<-- I pass this so login was OK
});
});
}));
...
var app = express();
app.set('view engine', 'ejs');
app.use(less(path.join(__dirname, 'public')));
app.use(express.static(path.join(__dirname, 'public')));
app.use(cookieParser());
app.use(session({ secret: '123', resave: true, saveUninitialized: true }));
app.use(passport.initialize());
app.use(passport.session());
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(flash({ locals: 'flash' }));
...
app.post(
'/login',
passport.authenticate(
'local',
{ successRedirect: '/enquete', // <--- Please read below note on this
failureRedirect: '/login' }));
function ensureLocalAuthenticated(req, res, next) {
if (req.isAuthenticated()) { return next(); }
res.redirect('/login');
}
app.get(
'/enquete',
ensureLocalAuthenticated,
function(req, res) {
res.render('pages/enquete');
});
Note:
I have debugged passport.authenticate to make sure the login indeed succeeds. Since I am providing successRedirect option then return res.redirect(options.successRedirect); happens near node_modules/passport/lib/middleware/authenticate.js:245. I have checked req.isAuthorized() is indeed true prior the redirect.
However in ensureLocalAuthenticated req.isAuthorized is false. Why?!
I am lost. Any help is appreciated
Silly but it makes sense. I found that the reason was the order of the middleware were wrong! (facepalm). Changing the code to this made my server work as expected.
var app = express();
app.set('view engine', 'ejs');
app.use(less(path.join(__dirname, 'public')));
app.use(express.static(path.join(__dirname, 'public')));
app.use(cookieParser());
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(session({ secret: '123', resave: true, saveUninitialized: true }));
app.use(flash({ locals: 'flash' }));
app.use(passport.initialize());
app.use(passport.session());
I would like to use the req.flash that was removed as of Express 3.0. According the docs, simply configure the app as so to use it:
app.configure(function() {
app.use(express.cookieParser('keyboard cat'));
app.use(express.session({ cookie: { maxAge: 60000 }}));
app.use(flash());
});
However, I've configured my app as so:
app.configure('production', function() {
app.use(express.static('/static', express.static(__dirname + '/lib/static')));
app.use(express.errorHandler());
app.use(express.cookieParser('keyboard cat'));
app.use(express.session({ cookie: { maxAge: 60000 }}));
app.use(flash());
app.use(passport.initialize());
app.use(passport.session());
app.use(app.router);
});
I've been trying to detect the availability of flash as so:
app.all('/*', function(req, res, next) {
console.log('FLASH: ', req.flash);
....
My logs show the following:
FLASH: undefined
FLASH: undefined
FLASH: function _flash(type, msg) {....
This was displayed with just one request to the '/' route. I understand why there may be multiple requests with the one GET request to '/', however, I'm wondering why req.flash is not available on every request as the docs state.
I think you should change your configuration to:
app.configure('production', function() {
app.use(express.errorHandler());
app.use(express.cookieParser('keyboard cat'));
app.use(express.session({ cookie: { maxAge: 60000 }}));
app.use(flash());
app.use(passport.initialize());
app.use(passport.session());
app.use(express.static('/static', express.static(__dirname + '/lib/static')));
app.use(app.router);
});
I always keep my static route at the end of my middleware.
I think the problem is that your /* route is also firing for /static requests and, since that middleware is declared before the flash() middleware, the request object hasn't yet been modified.