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
});
Related
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)
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('/');
}
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);
I'm trying to build a server that user will be able to enter these valid paths:
/art/thisProject
/art/thatProject
and in case the user enters anything else invalid such as these the user will be redirected to root and then to the default path /art/myProject:
/some/url
/something
/another/u/rl
I guess the error comes because of a false use of "*"or with false understanding of how to override router rules.
How do I do it?
this is my code:
app.get('/', function(req, res) {
res.redirect('/art/myProject')
});
app.get('/art/:project', function(req, res){
var project = req.param('project');
var filePath = 'art/' + project + '/' + project;
res.render(filePath)
});
app.get('*', function(req, res) {
res.redirect('/')
});
This should work:
app.get('/*', function(req, res) {
res.redirect('/')
});
Or this:
app.use(function(req, res) {
res.redirect('/')
});
Both must of course be put last.
What i'm trying to do:
If the url exists in the db use static page template, if not, display specific page template. Can't seem to figure out, how too...
My app.js file
app.get('*', function(req, res){
var currenturl = req.url;
console.log('URL IS: ' + my_path)
if (!!db.get(my_path) )
{
//If it does exist in db
console.log('Does exist');
res.render('index', { thetitle: 'Express', title: db.get(currenturl).title, content: db.get(currenturl).content });
}else{
//If it doesn't exist in db
redirect to other sites
Like:
if you go to "/page" it will run this => app.get('/page', routes.index)
or "/users" will run => app.get('/users', routes.users)
}
});
You have to create your own simple middleware. Just make sure you put it above the express.router
app.use(function(req, res, next){
if (!!db.get(my_path)) {
// render your site from db
} else {
// call next() to continue with your normal routes
next();
}
});
app.get('/existsInDB', function(req, res) {
// should be intercepted by the middleware
})
app.get('/page', function(req, res) {
// should not be intercepted
res.render('page')
})
using express is easy. you can use the redirect function:
if (url_exists) res.render('index');
else res.redirect('/foo/bar');