stacking of routes in node.js - javascript

var express = require('express');
var router = express.Router();
router.use(function(req, res, next){
console.log(req.user)
if(!req.user){
res.redirect('/login');
}else{
res.locals.username = req.user.username;
return next();
}
});
//this won't work
router.get('/register', function(req, res, next) {
res.render('register');
});
The first block make sense and it's working,I able to have a login system with protected routes. But in the same time it ruined my second bit, it will show the login page althought I try to nagivate to localhost:3000/register.

When you're using router.use() you're telling the router to use that function middleware in all the next roter.get() routes. So here, the order makes sense. If you care about order you can do what #bloodyKnuckles do. Or if you want to keep that pattern for your routes you can do the following :
// Routes that don't need authorization like register
router.get('home',...);
router.get('register',...);
// Use your authorization middleware
router.use(function(req, res, next){
console.log(req.user)
if(!req.user){
res.redirect('/login');
}else {
res.locals.username = req.user.username;
return next();
}
});
// At this point you're using the authorization middleware.
// Any routes declared from here will call authorization middleware before its handler.
router.get('profile', ...);

Use the express route middleware option to distinguish protected routes from unprotected routes.
// unprotected routes (no auth middleware)
router.get('/login', function(req, res, next) {
res.render('login');
});
router.get('/register', function(req, res, next) {
res.render('register');
});
// protected route (see auth middleware here)
router.get('/userinfo', authorize, function(req, res, next) {
res.render('userinfo');
});
function authorize (req, res, next){
console.log(req.user)
if(!req.user){
res.redirect('/login');
}else{
res.locals.username = req.user.username;
return next();
}
}
Include your authorization middleware ONLY in the protected routes:
router.get(path, [middleware (optional),] callback)

Related

how can handle multpile oauth request from frondend in single routr

IS there any way i can dynamic take the platform info and process them,even when i tried accessing the value outside the function it is not working since it is a single route file
router.get(
"/:platform",
function data(req, res, next) {
var platform = req.params.platform;
next();
},
passport.authenticate("google", { scope: ["email"] })
);
You can save the data in req and then run the middleware manually
This should work, but I didn't test it
router.get(
"/:platform",
function data(req, res, next) {
req.platform = req.params.platform;
next();
},
(req, res, next) => passport.authenticate(req.platform, { scope: ["email"] })(req, res, next)
);

Node.JS authorization

I want to create a simple application with auth system. When someone visits my page server must return authorization html page, than visitor can fill the inputs and send login and password through socket.io to server. And if the values are correct, server sends second html page to client. I know that I can use this code and redirect on client side:
app.get('/page1', function(req, res){
res.sendFile(__dirname + '/page1.html');
});
app.get('/page2', function(req, res){
res.sendFile(__dirname + '/page2.html');
});
But I want users to always stay on the same address, it must always be example.com/
You can use express middleware for authentication.
function authCheck(req,res,next){
//Your auth check will be here
if(isValidUser){
next();
}
else{
res.sendFile(__dirname + '/login.html');
}
}
app.get('/afterlogin', authCheck, function(req, res){
res.sendFile(__dirname + '/afterlogin.html');
});
You can use Passport for authentication provider.
Then you can register some authentication middleware like so:
// auth.js
module.exports = {
isGuest: (req, res, next) => {
if (req.isAuthenticated()) {
res.redirect('/');
} else {
next();
}
},
isAuthenticated: (req, res, next) => {
if (req.isAuthenticated()) {
next()
} else {
res.redirect('/users/login')
}
},
};
Then you can apply the middleware on your routes like so:
// users.js
let express = require('express'),
router = express.Router(),
usersController = require('../controllers/usersController'),
auth = require('../middlewares/auth');
router.get('/register', auth.isGuest, (req, res) => {
usersController.showRegisterPage(req, res);
});
router.post('/register', auth.isGuest, (req, res) => {
usersController.register(req, res);
});
router.get('/login', auth.isGuest, (req, res) => {
usersController.showLoginPage(req, res);
});
router.post('/login', auth.isGuest, (req, res) => {
usersController.login(req, res);
});
router.post('/logout', (req, res) => {
usersController.logout(req, res);
});
router.get('/profile/:username', auth.isAuthenticated, (req, res) => {
usersController.showProfilePage(req, res);
});
Hope this helps.

NodeJS Passport redirect

I am trying to implement user redirection with Passport on NodeJS and Express Backend script. The issue that I am facing is that my login page is not my default home page but it's rather this:
localhost:3000/login
I've managed to make it so that if user is not registered, he cannot access other pages such as /index or /dashboard but something breaks when I try to access hard-coded urls such as:
If I enter localhost:3000/ I can gain access to the default index.html page even if I'm not logged in. Just to clarify - localhost:3000/index == localhost:3000.
If I decide to manipulate the route like this: localhost:3000/Example/pages/index.html or localhost:3000/Example/pages/dashboard.html it would allow me to access the pages even if I am logged in.
My question is, how can I restrict users to manipulate the route to the default homepage and any other pages which have not been declared in the Node Backend?
My Node Routes Code:
app.get('/login',
function(req, res){
res.sendFile(path.join(__dirname + '/login.html'));
});
app.get('/index', isLoggedIn,
function(req, res){
res.sendFile(path.join(__dirname + '/index.html'));
});
app.post('/login',
passport.authenticate('local', { failureRedirect: '/login' }),
function(req, res) {
res.redirect('/index');
});
app.post('/login',
passport.authenticate('local', { failureRedirect: '/login' }),
function(req, res) {
res.redirect('/index');
});
I've tried using this:
app.use(function(req, res, next) {
if (req.session.user == undefined) {
return res.render('/login', { failureRedirect:'/login' });
}
else {
next();
}
});
but I receive an error: No default engine was specified and no extension was provided. I don't want to use JADE or Handlebars or anything else as an engine, just static HTML.
How can I restrict the route manipulation without having to define the rest of my node pages as app.get(/something, function(req,res){});
You can make a passport middleware to check if the user is authenticated
isAuthenticated = (req, res, next) => {
if (req.isAuthenticated()) {
return next();
}
res.redirect('/login');
};
And then you can do this
app.get('/someroute', isAuthenticated, (req, res)=>{
// do what you want
});

How to pass arguments into an outside module?

I have the following function that I placed inside a separate js file.
I am trying to use it inside another javascript file that requires passport.js, and I would like to call it using app.use to further modularize my application
var express = require('express');
var router = express.Router();
/* GET welcome page. */
router.get('/home', isLoggedIn, function(req, res, next) {
res.render('home', {
title: 'title',
user : req.user
});
});
// route middleware to make sure
function isLoggedIn(req, res, next) {
// if user is authenticated in the session
if (req.isAuthenticated())
return next();
// if they aren't redirect them to the home page
res.redirect('/');
}
module.exports = router;
The reason I created it is so I reduce redundancy and not use the following code each time:
app.get('/home', isLoggedIn, function(req, res) {
res.render('home.ejs', {
user : req.user // get the user out of session and pass to template
});
});
However I can't seem to get it to work. is authenticated is undefined although it is in the same folder, and it gives me an error 404 not found when I issue a get. How I can keep it in an external file and still use it? should I also pass it the user argument from where I am calling it?
var express = require('express');
var router = express.Router();
module.exports = function (app, passport){
router.get('/home', isLoggedIn, function(req, res, next) {
res.render('home', {
title: 'title',
user : req.user
});
});
return router;
};
function isLoggedIn(req, res, next) {
// if user is logged in -
if (req.isAuthenticated())
return next();
// if they aren't redirect them to home
res.redirect('/');
}

Express4.js - route only if there is an active passport.js session

I am using passport.js and express4.js. I would like to know if there is an automatic way to verify if the client as opened a session with passport.js when he try to access a view?
Actually I am doing like this to verify if the client can access an url:
router.get('/[0-9]{3}/', function(req, res, next){
var path_codecs = req.originalUrl.split('/')[2];
if (!req.user) {
res.redirect('/login');
}
if (req.user.dataValues.codecs !== path_codecs) {
next();
}
res.render('decoupage')
});
Do I have to do this verification at each view I want to restrict to session user or is there a more automatic way to define what views can be accessed and not?
You can use req.user (which Passport will set after a successful authentication).
I usually use this in a thin middleware like so:
function isAuthenticatedMiddleware (req, res, next) {
if (req.user) { return next(); }
next('AuthenticationError');
}
router.get('/[0-9]{3}/', isAuthenticatedMiddleware, function(req, res, next){
You can easily add this to all routes on a router with express's router.all
router.all('*', isAuthenticatedMiddleware);

Categories