maintaining session on different routes - node.js

How do you maintain session between route.
I have 3 routes
var routes = require('./routes/index');
var users = require('./routes/users');
var question = require('./routes/question');
app.use('/', routes);
app.use('/users', users);
app.use('/question',question);
on top of the 3 js file is this:
var express = require('express');
var router = express.Router();
this created a new router thus losing the session i guess?
within users, i use passport to create a login system, by its default serializer the user information is saved under req.user but only accessible within users route.
I would like to use the session within routes(index) and question route. How do i solve this?
thanks,

As you mentioned that you have defined each request specific route in its separate file.
Then you donot need to define these line again in main file.
var express = require('express');
var router = express.Router();
app.use(passport.session());
function ensureAuthenticated(req, res, next) {
// passport.js provides this method req.isAuthenticated())
if (req.isAuthenticated())
return next();
else
// Return error content: res.jsonp(...) or redirect: res.redirect('/login')
}
Here, you can define your strategy to check routes. If it is authenticate then disclose user related information.
app.use('/', ensureAuthenticated, routes);

Related

Routes passport-local

I am trying to use passport-local to restrict access of a website.
For this I am using login_app for running passport-local, however this is in itself a route that is called from the main app.js.
While trying to route on a 2nd level (passport-files/routes) I find that my code is found, but the functions inside are not called.
This is my login_app code:
var express = require('express');
var router = express.Router();
var mongoose = require ('mongoose');
var flash = require('connect-flash');
var passport = require('passport');
var LocalStrategy = require('passport-local').Strategy;
var morgan = require('morgan');
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');
var session = require('express-session');
let app = express();
// pass passport for configuration
require('./passport-files/passport')(passport);
//For express application
app.use(morgan('dev'));
app.use(cookieParser()); // read cookies (needed for auth)
app.use(bodyParser()); // get information from html forms
//Initialize passport session
app.use(session({ secret: 'secret' })); // session secret
app.use(passport.initialize());
app.use(passport.session());
app.use(flash()); // use connect-flash for flash messages stored in session
// load our routes and pass in our app and fully configured passport
require('./passport-files/routes')(app, passport);
module.exports = router;
To simplify the question I am only putting the routes.js file here:
var express = require('express');
var router = express.Router();
let app = express();
module.exports = function (app, passport) {
//function views (app, passport) {
/* GET users listing. */
// HOME PAGE (with login links) ========
app.get('/', function(req, res) {
res.render('login-welcome', {});
});
// LOGIN ===============================
// show the login form
app.get('/log-in', function(req, res) {
res.render('login', { message: req.flash('loginMessage') });
});
// process the login form
app.post('/log-in', passport.authenticate('local-login', {
successRedirect : '/admin', // redirect to the secure profile section
failureRedirect : '/log-in', // redirect back to the signup page if there is an error
failureFlash : true // allow flash messages
}));
// we will use route middleware to verify this (the isLoggedIn function)
app.get('/profile', isLoggedIn, function(req, res) {
res.render('profile', {
user : req.user // get the user out of session and pass to template
});
});
app.get('/logout', function(req, res) {
req.logout();
res.redirect('/');
});
};
// route middleware to make sure a user is logged in
function isLoggedIn(req, res, next) {
// if user is authenticated in the session, carry on
if (req.isAuthenticated())
return next();
// if they aren't redirect them to the hosme page
res.redirect('/');
};
I pretty much built this using the example from scotch.io ( https://scotch.io/tutorials/easy-node-authentication-setup-and-local ), however I cannot get it to work this way.
If i write the routes directly into login_app, they are recognized, even though the authentification still does not work.
Do any of you have an idea how to solve this? Is more information required?
This may be the problem: in your login_app module you're exporting router, however you haven't actually defined any routes on router, they're all defined on a new instance of an app.
A simple example creating a router in one file, and exporting it to use in a main app.js file, would be like this:
/** app.js */
var express = require('express');
var app = express();
var myRoutes = require('./routes');
app.use(myRoutes);
app.listen(3000);
/** routes.js */
// instaniate a new router, add routes/middleware on it, and export it
var router = require('express').Router();
// define your routes and middleware here
// router.use( ... )
module.exports = router;
Another pattern, which I think the scotch.io tutorial is using, is to have the routes file export a function into which you pass your main app instance. Then the two files would look like this:
/** app.js */
var express = require('express');
var app = express();
require('./routes')(app); // pass your main `app` instance into the function
app.listen(3000);
/** routes.js */
module.export = function(app) {
// define all your routes and middleware here directly on the `app` that gets passed in
// app.use( ... )
}

Nodejs Express router.get('/') in users.js

I m still trying to learn NodeJs but I came across this path thing I encountered in Express. When I create an app using Express I noticed that in app.js I have these lines of code var index = require('./routes/index');
var users = require('./routes/users');
app.use('/', index);
app.use('/users', users);
And in users.js I already have configured
var express = require('express');
var router = express.Router();
/* GET users listing. */
router.get('/', function(req, res, next) {
res.send('respond with a resource');
});
module.exports = router;
I don t really understand why is it in users.js router.get('/') instead of router.get('/users') as it is specified in app.js? Can someone explain a bit what s going on in this case?
As far as I understand in app.js it says whenever someone tries to access the specified route('/users') lets say localhost:3000/users in the browser, let the file required in users variable handle it.
If you are working with routes the express app is automatically . Here is an example from the express.js website:
In our router file we have:
var express = require('express')
var router = express.Router()
// middleware that is specific to this router
router.use(function timeLog (req, res, next) {
console.log('Time: ', Date.now())
next()
})
// define the home page route
router.get('/', function (req, res) {
res.send('Birds home page')
})
// define the about route
router.get('/about', function (req, res) {
res.send('About birds')
})
module.exports = router
Then in our main file were we have our server etc we load in the router:
var birds = require('./birds')
// ...
app.use('/birds', birds)
These routes in the router app are only accessed when there is a request to to /birds url. All the routes in the router are now automatically staring with /birds
So this code in the express router:
// im code in the birds router
router.get('/about', function (req, res) {
res.send('About birds')
})
Is only executed when someone makes a get request to the /birds/about url.
More information in the official express.js docs
I would just like to point out what I have learnt today after some frustration, and maybe somebody can elaborate as to why this happens. Anyway, if, like me, you want to use '/users' for all user routes or '/admin' for all administrator routes then, as WillemvanderVeen mentioned above, you need to add the following code to your main app.js file
var users = require('./routes/users')
app.use('/users', users)
However, one thing which was not mentioned is that the order with which you declare your 'app.use('/users', users)' in app.js is important. For example, you would have two route handling files as so:
/routes/index.js
const express = require('express');
const router = express.Router();
router.get('/', (req, res) => { res.render('index') });
/routes/users.js
const express = require('express'); const router = express.Router();
router.get('/', (req, res) => { res.send('users route') })
You would then require them in your main app.js file as so:
app.js
const express = require('express');
const app = express();
const index = require('./routes/index');
const users = require('./routes/users');
app.use('/', index);
app.use('/users', users);
and you would expect that when you hit the '/users' route that you would receive the res.send('users route') page.
This did not work for me, and I struggled to find any solution until recently, which is why I am now commenting to help you.
Instead, I swapped the app.use() declarations in app.js around like so and it worked:
app.js
const express = require('express');
const app = express();
const index = require('./routes/index');
const users = require('./routes/users');
app.use('/users', users);
app.use('/', index);
Now when I hit '/users' I see the 'users route' message. Hope this helped.
To answer your question though, when you configure the route handler in app.js as users, then you are requiring a router file (./routes/users) to handle all requests from that file and sending them to the URL /users first. So if you do the following:
/routes/users.js
router.get('/dashboard', (req, res) => {
// get user data based on id and render it
res.render('dashboard')
});
then whenever user is logged in and goes to dashboard, the URL will be /users/dashboard.

express4 router skipping base route and going directly to a sub-route

I have an express4 router that is skipping the base route and going directly to a designated ./user route. But I can not see why it is skipping the base route.
APP.js
var express = require('express');
var path = require('path');
var logger = require('morgan');
var bodyParser = require('body-parser');
var router = express.Router();
var app = express();
require('./routes')(app);
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
//app.use('/', router);
module.exports = app;
./routes/index.js
var express = require('express');
var router = express.Router();
// route middleware that will happen on every request
router.use(function(req, res, next) {
// log each request to the console
console.log(req.method, req.url);
// continue doing what we were doing and go to the route
next();
});
/* GET home page. */
router.get('/', function(req, res) {
console.log('inside the root route');
});
//module.exports = router;
module.exports = function(app) {
// here we list our individual sets of routes to use in the router
require('./route/user')(app);
};
When I run the app (npm start), console displays the log that resides inside the user route and totally skips the base route ('/').
Where did I go wrong??
It appears that you are only exporting the user routes.
To make this a bit clearer, app.js only has access to the following when you require routes.index.js:
function(app) {
// here we list our individual sets of routes to use in the router
require('./route/user')(app);
};
hence why it is skipping the base route entirely.
Following the API documentation (under the 'express.Router' section), the correct code to export the routes would be:
// exports the router.use and router.get('/) routes
module.exports = router
Which would mean you'd have to include the user routes in another section (such as app.js).

How can I make one page in my node.js app use multiple route files?

Sorry ahead of time if this sounds confusing, or has been answered before.
Using node.js, express and express-generator, I created an app that has two route files:
The first route file does MySQL database interaction and returns the result of queries (used for displaying data on the home and admin pages).
The second route file uses an LDAP server for checking login credentials, as well as managing login sessions (used for checking authorization on the login and admin pages).
Both routes requires express to function, but if I require express in both route files it gives me an error. Is there a way to allow both route files to use the same express router?
app.js
var express = require('express');
// Other generated requires
var data = require('./routes/data');
var auth = require('./routes/auth');
var app = express();
// Other generated sets and uses
app.use('/', data);
// "login" and "admin" need to use both data.js and auth.js <----------------
//app.use('/login', data);
//app.use('/login', auth);
//app.use('/admin', data);
//app.use('/admin', auth);
module.exports = app;
routes/data.js
var express = require('express');
var router = express.Router();
// Database functions
router.get('/', function (request, response) {
response.render('index');
});
module.exports = router;
routes/auth.js
var express = require('express');
var session = require('express-session');
var directory = require('activedirectory');
var router = express.Router();
// Login and session functions
router.get('/login', function (request, response) {
// Login and session check
response.render('login');
});
router.get('/admin', function (request, response, next) {
// Session check
response.render('admin');
});
module.exports = router;

route separation with express router and passing instances

So I'm trying to separate all my routes and organize them. I've manage to do that, but I face an issue. Using express 4, and the router I am having a problem passing an instance of something to a particular route. For example I want to pass passport to the login.js file. How would I do that? Am I doing this the correct way, or is there a better more cleaner solution?
//app.js
var express = require('express');
var passport = require('passport');
var app = express();
require('./routes')(app, passport);
//routes.js
module.exports = function (app, passport) {
app.use('/', require('./routes/index'));
app.use('/', require('./routes/login')(passport));
app.use('/', require('./routes/register')(passport));
};
//login.js
Here passport is undefined.
var express = require('express');
var router = express.Router();
router.get('/login', function (req, res) {
res.render('login', {
title: 'login',
message: req.flash('loginMessage')
});
});
router.post('/login', passport.authenticate('local-login', {
successRedirect : '/profile',
failureRedirect : '/login',
failureFlash : true
}));
module.exports = router;
So there's two ways folks do this, and there's pros and cons to each.
Easiest is to have your passport config in a file of your own (i.e. where you setup all your passport strategies, etc), and that file exports the passport object after setting it up.
e.g.
/* in ./lib/passport.js */
module.exports = passport;
Then in some other file that needs it, you just require your passport file (code in there only gets called once, and the exported module is cached after that).
/* in some other file */
var passport = require('./lib/passport');
this has the advantage of simplicity, but a lot of folks feel (rightly so) that it's not quite as testable if you're doing unit tests, b/c you can't isolate the file under test as easily, etc.
so in that case, each module file will export a function which takes its dependencies in through a function. For example,
/* in your router file */
var router = require('express').Router();
var loginRoutes = function(passport){
router.post('/login', passport.authenticate('local-login', {
successRedirect: '/profile',
failureRedirect: '/login'
}));
return router;
};
module.exports = loginRoutes;
then wherever you're pulling the routes into the app, that process just requires the route file and calls the function, passing it the passport instance. which looks like what you did in routes.js.

Resources