Search code examples
javascriptnode.jsexpressauthenticationexpress-session

NodeJS - Express - Sessions - Redirect to secure page


I'm trying to set up a "backend" for a webpage I've created. So some pages can only be accessible if the user is logged in. I've built the basic functionality for this and I can do a simple validation in whether the user is logged-in. But the redirecting to the page is where I get stuck.

Example:

var auth = function(req,res,next){
    if (req.session.loggedin){
        return next();
    } else{
        return res.sendStatus(401);
    }
};

app.get('/list-video', auth, function (req, res) {
    res.redirect('/list-video');
});

So my issue is that '/list-video' is the page I want to protect and only be accessible when the user successfully logged in. But after the validation, I'm redirecting to the same page: '/list-video'. this doesn't seem to work as I'm obviously getting stuck in a loop. I have tried redirecting to a different page like '/list-audio' and of course this works fine.

Can someone advise on how this is usually done? Do I need to create a separate link that I can redirect to? (I do want to prevent users going to that link manually by typing the URL in the browser.)

Any help or advice will be greatly appreciated!

My complete app.js code:

const express = require('express');
const fileUpload = require('express-fileupload');
const bodyParser = require('body-parser');
const mysql = require('mysql');
const path = require('path');
const app = express();
const session = require('express-session');

const { getHomePage } = require('./routes/index');

const { getBackendPage } = require('./routes/backend');
const { getVideoPage, listVideoPage, editVideoPage, editVideo, deleteVideo, addVideoPage, addVideo } = require('./routes/video');
const { getEbookPage } = require('./routes/ebook');
const { getMusicPage } = require('./routes/music');
const { getGamePage } = require('./routes/game');
const { getShopPage } = require('./routes/shop');

const port = 5000;


const db = mysql.createConnection({
    host: '127.0.0.1',
    user: 'user',
    password: 'bla',
    database: 'test'
    
    db.connect((err) => {
    if (err) {
        throw err;
    }
    console.log('Connected to database');
});
global.db = db;

// configure middleware
app.set('port', process.env.port || port); // set express to use this port
app.set('views', __dirname + '/views'); // set express to look in this folder to render our view
app.set('view engine', 'ejs'); // configure template engine
app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json()); // parse form data client
app.use(express.static(path.join(__dirname, 'public'))); // configure express to use public folder
app.use(fileUpload()); // configure fileupload
app.use(session({
    secret: 'secret',
    resave: true,
    saveUninitialized: true
}));
app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());
    
    
/ passenger views
app.get('/', getHomePage);
app.get('/backend', getBackendPage);
app.get('/video', getVideoPage);
app.get('/ebook', getEbookPage);
app.get('/music/:id', getMusicPage);
app.get('/game', getGamePage);
app.get('/shop', getShopPage);

// backend views video
app.get('/edit-video/:id', editVideoPage);
app.post('/edit-video/:id', editVideo);
app.get('/add-video', addVideoPage);
app.post('/add-video', addVideo);
app.get('/delete-video/:id', deleteVideo);


// login screen
app.post('/auth', function (request, response) {
    var username = request.body.username;
    var password = request.body.password;
    if (username && password) {
        db.query('SELECT * FROM accounts WHERE username = ? AND password = ?', [username, password], function (error, results, fields) {
            if (results.length > 0) {
                request.session.loggedin = true;
                request.session.username = username;
                response.redirect('/');
            } else {
                response.send('Incorrect Username and/or Password!');
            }
            response.end();
        });
    } else {
        response.send('Please enter Username and Password!');
        response.end();
    }
});

var auth = function(req,res,next){
    if (req.session.loggedin){
        return next();
    } else{
        return res.sendStatus(401);
    }
};

app.get('/list-video', auth, function (req, res) {
    res.redirect('/list-video');
});

  app.listen(port, () => {
    console.log(`Server running on port: http://localhost:${port}`);
});  


Solution

  • Move your protected pages to a different directory (outside the folder where your public static files are) and serve the express.static after the authentication middleware, something like this:

    app.use('/', express.static(path.join(__dirname, 'public'))); //notice I have no auth middleware
    app.use('/mysecretpages', auth, express.static(path.join(__dirname, 'secret'))); //notice I DO have auth middleware