node.js express-session not working in router - node.js

i have a some problem
i'm using express-session middleware in my app
it work
but
It did not work on any particular router.
my code is follows
//app.js
app.use(session({
secret: 'D$YTRH#%#$#^$#YR',
resave: false,
saveUninitialized: true,
}))
//assign session in outside
app.get(/*, (req, res, next)=>{
req.session.outSide = "outSideBlah"
next()
}
//my session Check middleware
app.get('/*', (req, res, next)=>{
console.log(req.session._inSide)
console.log(req.session._outSide)
next()
}
const auth = require('./routes/auth.js')(express)
app.use('/auth', auth)
//auth.js (my router)
//assign session in router ( inside)
module.exports = (express) => {
const auth = express.Router()
auth.post('/login', (req, res)=>{
req.session._inside = 'insideBlah' //Assign a session here
............some auth code ......
}
return auth
}
after login
in my session Check middleware
console.log(req.session.inSide) // undefined
console.log(req.session.outSide) // "outSideBlah"
Even though I assigned req.session.inSide in auth.js
req.session.inside is undefined
What is the problem?
Why can not I access a session assigned by my router (auth.js)?
somebody help me.. thank you...

Also I think you should use * instead of /*.

Related

Adding isAuthenticated in Node.js route doesn't protect from non-authenticated access

I want to add a login feature to this web app https://github.com/squallooo/MT5 and protect the '/' route by adding isAuthenticated using passport.js, but no luck. I even deleted the index route to see what happens, but the index view still shows, thus I think I'm modifying the wrong code? Could anyone give me the tips where I need to modify the code in this case? I want the users to be redirected to the '/login' route when accessing '/' route.
my /config/auth file.
module.exports = {
ensureAuthenticated: function(req, res, next){
if(req.isAuthenticated()){
return next();
}
req.flash('error_msg', 'Please login to view this resource');
res.redirect('/login');
}
}
my index route
// Passport, Session
var session = require('express-session');
var passport = require('passport');
// session config
app.use(session({
secret: "secret",
saveUninitialized: true,
resave: true
}));
// Passport
app.use(passport.initialize());
app.use(passport.session());
var { ensureAuthenticated } = require('./config/auth');
// I want to protect the routing by adding 'ensureAuthenticated'
app.get('/', ensureAuthenticated, function (req, res) {
res.sendfile(__dirname + '/index.html');
});
I think I have found a temporary answer. For some reason, app.get('/', ...) route was not working. When I installed ejs (template engine) and then app.get('/', ...) route is working. I am able to protect this route from non-authenticated users now.

Issue: Node Express can't get session value with post request

I am developing a Shopify App in node.js. I am using different Shopify webhooks for different actions. similarly for a specific scenario I need to use session value while I am getting response from Shopify API. So in this scenario the session is not working for me. Please have a look on below code.
My code in index.js
const express = require('express');
const app = express();
var session = require('express-session');
app.set('trust proxy', 1); // trust first proxy
app.use(session({
secret: 'keyboard cat',
resave: false,
saveUninitialized: true,
cookie: {
httpOnly: false,
secure: true,
maxAge: 60000
}
}));
//Set the session
app.get('/check_timewindow_orders', function (req, res, next) {
req.session.delvy_date = query.date_select;
});
app.use(function (req, res, next) {
res.locals.delvy_date = req.session.delvy_date;
next();
});
I get the session value in app.get and app.post.
app.get('/order_created_get', function (req, res) {
console.log(req.cookies.delDate);
// It display the value store in session.
});
But I cannot get the session value when I get the post from shopify Order Create Webhook API.
app.post('/order_created', function (req, res) {
console.log(req.cookies.delDate); // It display Null.
});
You are not actually using the session.
You need to add it as middleware:
app.get('/check_timewindow_orders', session, function(req, res, next){
req.session.delvy_date = req.query.date_select;
});
app.use(session, function(req, res, next) {
res.locals.delvy_date = req.session.delvy_date;
next();
});

req.session is undefined express-session

I know this question has been asked several times. However, none of the answers I've read has solved my question.
Many of them were outdated for express v4, as express-session is currently a separate module. Those question/answers are here:
'session' is undefined when using express / redis for session store
req.session undefined in Express.js
nodejs express req.session undefined
Other questions are updated, however the solution given doesn't fix my problem. Those question/answers are here:
NodeJS express-session req.session is undefined
req.session is undefined using express-session
Most of the solutions are the sequence of middlewares when configuring the app. I've tried different options and I doesn't find the correct way to do it. Maybe it's just that.
In other solution, someone says that session middleware cannot be called, because if it were, req.session would be defined. I've used middlewares just before an after app.use(session({...})), and checked that both get called.
I've also found in this issue someone saying that he gets req.session undefined when the store disconnects. I'm using the default store so far. Could this be the problem?
I'm getting this error:
TypeError: Cannot read property 'destroy' of undefined
It breaks just when I try to logout a session with req.session.destroy() at login.js (see code below)
My code
server.js
const express = require('express');
const session = require('express-session');
const mongo = require('mongodb');
const passport = require('passport');
const path = require('path');
const routes = require('./app/routes');
const login = require('./app/routes/login.js');
const app = express();
app.use(session({
secret: 'key',
resave: false,
saveUninitialized: true,
}));
app.use(passport.initialize());
app.use(passport.session());
app.use('/public', express.static(path.normalize('./public')));
app.use(routes);
app.use(login);
app.set('view engine', 'pug');
const MongoClient = mongo.MongoClient;
MongoClient.connect('mongodb://localhost:27017/myapp')
.then((db) => {
// Link the database through the app. It will be available in the req.app object
app.db = db;
console.log('App listening on port ' + process.env.PORT);
app.listen(process.env.PORT);
})
.catch((err) => {
console.log('There was an error connecting to the database.');
console.log(err);
});
module.exports = app; // For testing
login.js
const express = require('express');
const passport = require('passport');
const router = new express.Router();
// Other login logic here
router.get('/logout', (res, req) => {
req.session.destroy((err) => {
req.redirect('/');
});
});
module.exports = router;
You swapped the req and res arguments in your handler:
router.get('/logout', (res, req) => { ... })
That should be the other way around:
router.get('/logout', (req, res) => { ... })

How to pass the configured passport object into the routes modules in Express4?

Since from Express 4 you're not supposed to do
require('./app/routes.js')(app, passport); // load our routes and pass in our app and fully configured passport
module.exports = function(app, passport) {
// =====================================
// FACEBOOK ROUTES =====================
// =====================================
// route for facebook authentication and login
app.get('/auth/facebook', passport.authenticate('facebook', { scope : 'email' }));
// handle the callback after facebook has authenticated the user
app.get('/auth/facebook/callback',
passport.authenticate('facebook', {
successRedirect : '/profile',
failureRedirect : '/'
}));
// route for logging out
app.get('/logout', function(req, res) {
req.logout();
res.redirect('/');
});
};
Instead, you're supposed to be using express.Route() function and
var routes = require('./app/routes.js');
app.use('/', routes);
How to pass the configured passport into the routes modules in Express 4?
The function export can still be used to pass the passport reference between modules. It would just create and return a Router rather than modifying the app directly.
var express = require('express');
module.exports = function(passport) {
var router = express.Router();
router.get('/auth/facebook', passport.authenticate('facebook', { scope : 'email' }));
// etc.
return router;
};
And, the app can then use it with:
var routes = require('./app/routes.js')(passport);
app.use('/', routes);

Second router or middleware path in express.js

I have the usual middleware stack for my app:
app.configure(function() {
app.use(express.static(PUBLIC_DIR));
app.use(express.favicon());
app.use(express.bodyParser({
keepExtensions: true,
uploadDir: '/tmp/neighr'
}));
app.use(express.methodOverride());
app.use(express.cookieParser());
app.use(express.session({
secret: '***REDACTED***',
store: sessionStore,
}));
app.use(express.csrf());
app.use((require('connect-flash'))());
app.use(passport.initialize());
app.use(passport.session());
app.use(function(req, res, next) {
app.locals({
_csrf: req.session._csrf,
url: req.url,
user: req.user,
authenticated: req.isAuthenticated(),
messages: {
info: req.flash('info'),
error: req.flash('error'),
success: req.flash('success')
}
});
next();
});
app.use(app.router);
app.use(express.logger());
app.use(express.errorHandler());
});
As you can see, the express.static is one of the first in the stack, so that static resources will be served without going through the entire session stuff which only makes loading times longer.
I do have, however, some dynamic data I'd like to serve without all the session stuff:
app.get('/avatar/:id', function(req, res) {
var fid = res.params.id;
/* load binary from database */
res.send(data);
});
This route is within app.router, at the end of the stack. I would like to keep the way to declare this and other routes, but how can I get express to parse these before the session middleware?
There might be more such dynamic routes in the future, with more parameters.
Once you declare a route, Express inserts the router middleware into the middleware stack at that point, so if you were to declare a single route before loading the session middleware, all route requests would skip the session middleware:
app.get('/one', ...); // inserts `app.router` into the stack at this point
app.use(express.session(...));
app.get('/two', ...); // will skip the session middleware
There's two solutions I can think of: create your own middleware to handle the requests which shouldn't be passed through the session middleware, or explicitly set the session middleware for each route you want to run through it.
First solution:
app.use(function(req, res, next) {
if (req.path.indexOf('/avatar/') === 0) {
// parse out the `id` and return a response
}
next();
});
This obviously isn't very flexible.
Second solution:
// instantiate the session middleware:
var sessionMiddleware = express.session(...);
// default setup: insert the router before the session middleware:
app.use(app.router);
app.use(sessionMiddleware);
// Pass it explicitly to the route:
app.get('/two', sessionMiddleware, function(req, res) {
...
});
In your situation, where you also use Passport, you might want an array of middleware:
var authMiddleware = [
express.session(...),
passport.initialize(),
passport.session()
];
app.get('/two', authMiddleware, ...);
Looking at how Express is implemented, I don't think it's possible to instantiate a second router (and get it to function properly).

Resources