Search code examples
node.jsformspostpughttp-status-code-404

NodeJS POST Form always return 404


I've been running through a problem and I can not find out what it is. I am using Express for this.

I have an "addUser" form which has the following Pug form :

form(action='/adduser', method='POST')

and I have try POST method in the app.js that doesn't work :

app.post("/adduser", function (req, res, info, next){
    console.log('This does not appear');
});

What I don't understand is why the following login POST method which is just right above the adduser works perfectly :

app.post("/login", passport.authenticate('local', {
    // login things
});

NB : At the beginning, the /adduser was in a router and was also returning 404, that's why I tried to move it in app.js .

Feel free to ask any informations that you need.

Anthony.

FULL CODE app.js:

var express = require('express');
var path = require('path');
var favicon = require('serve-favicon');
var logger = require('morgan');
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');
var escape = require('escape-html');

var stock = require('./routes/stock');

var app = express();

app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'pug');

// Variables pour le système d'users

var flash = require('connect-flash');
var crypto = require('crypto');
/* Login script */
var passport = require('passport');
var LocalStrategy = require('passport-local').Strategy;
var connection = require('./lib/dbconn');

var sess = require('express-session');
var Store = require('express-session').Store;
var BetterMemoryStore = require(__dirname + '/memory');
var store = new BetterMemoryStore({expires: 60 * 60, debug: true});
app.use(sess({
    name: 'StockInfo Sess.',
    secret: 'C3ci3stUnSup3rS3cr3t',
    store: store,
    resave: true,
    saveUninitialized: true
}));


//======================================================================================================================
// Configs =============================================================================================================
//======================================================================================================================

app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({extended: false}));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));

app.use(flash());
app.use(passport.initialize());
app.use(passport.session());

app.use('/stock', stock);

//passport Strategy -- the express session middleware before calling passport.session()
passport.use('local', new LocalStrategy({
        usernameField: 'username',
        passwordField: 'password',
        passReqToCallback: true //passback entire req to call back
    }, function (req, username, password, done) {
        if (!username || !password) {
            return done(null, false, req.flash('message', 'All fields are required.'));
        }

        var escapeData = escape(username);
        var comboPrenomNom = escapeData.split(".");
        var prenom = comboPrenomNom[0].toLowerCase();
        var nom = comboPrenomNom[1].toLowerCase();

        connection.query("SELECT id, password, salt FROM users WHERE prenom = ? and nom = ?", [prenom, nom], function (err, rows) {
            if (err) return done(req.flash('message', err));

            if (!rows.length) {
                return done(null, false, req.flash('message', 'Invalid username or password.'));
            }

            if (!(rows[0].password === crypto.createHash('sha256').update(rows[0].salt + escape(password)).digest('hex'))) {
                return done(null, false, req.flash('message', 'Invalid username or password.'));
            }

            req.session.user = rows[0].id;
            return done(null, rows[0].id);
        });
    }
));

passport.serializeUser(function (id, done) {
    done(null, id);
});

passport.deserializeUser(function (id, done) {
    connection.query("SELECT id, prenom, nom, hasChangedPass, rights FROM users WHERE id = " + id, function (err, rows) {
        done(err, rows[0]);
    });
});


//======================================================================================================================
// Routes ==============================================================================================================
//======================================================================================================================

app.get('/', function (req, res, next) {
    res.redirect('/login');
});


app.get('/login', function (req, res) {
    res.render('login/index', {
        title: 'LogIn',
        message: req.flash('message')
    });
});

app.post("/login", passport.authenticate('local', {
    successRedirect: '/stock',
    failureRedirect: '/login',
    failureFlash: true
}), function (req, res, info) {
    res.render('login/index', {
        'message': req.flash('message')
    });
});

app.post("/adduser", function (req, res, info, next) {
    if (req.body.prenom && req.body.nom && req.body.password) {
        var prenom = escape(req.body.prenom).toLowerCase();
        var nom = escape(req.body.nom).toLowerCase();
        connection.query("SELECT * FROM users WHERE prenom = ? and nom = ?", [prenom, nom], function (err, rows) {
            if (err) {
                console.log(err);
            }
            if (!rows.length) {
                var salt = generate_token(32);
                var password = escape(req.body.password);
                password = crypto.createHash('sha256').update(salt + '' + password).digest('hex');
                connection.query("INSERT INTO users (prenom, nom, password, salt) VALUES (?, ?, ?, ?);", [prenom, nom, password, salt], function (err) {
                    if (err) {
                        console.log(err);
                    }
                });
            }
        });
    } else {
        res.redirect('/stock/fromage');
    }
});


app.get('/logout', function (req, res) {
    req.session.destroy();
    req.logout();
    res.redirect('/login');
});


// 404
app.use(function (req, res, next) {
    var err = new Error('Not Found');
    err.status = 404;
    next(err);
});


// error handler
app.use(function (err, req, res, next) {
    // set locals, only providing error in development
    res.locals.message = err.message;
    res.locals.error = req.app.get('env') === 'development' ? err : {};

    // render the error page
    res.status(err.status || 500);
    res.render('error', {title: err.status});
});


function hasRights(req, res, next) {
    if (req.user.rights[0] == 1 || req.user.rights[1] == 2 || req.user.rights[2] == 2 || req.user.rights[3] == 2) {
        return next();
    }
    res.redirect('/stock');
}


function isAuthenticated(req, res, next) {
    if (req.session.user) {
        if (req.user.hasChangedPass) {
            return next();
        } else {
            res.redirect('/stock/initpass');
        }
    }
    res.redirect('/login');
}



module.exports = app;

/login/register.pug

extends ../layout
block content

    include ../templates/header

    .wrapper
        form(action='/adduser', method='POST')
            h3 Nouvel utilisateur

            div.form-row
                div.form-group
                    input.form-control(type='text', placeholder='Prénom', name='prenom' required)
            div.form-row
                div.form-group
                    input.form-control(type='text', placeholder='Nom', name='nom' required)
            div.form-row
                div.form-group
                    input.form-control(type='text', placeholder='Mot de Passe', name='password', value= pass required)
            div.form-row
                div.form-group
                    button.form-control Créer

            div.form-row
                div.form-group
                    p= rights

Solution

  • In your /adduser route you have 4 parameters in the callback function: (req, res, info, next). Remove info and Express will find your route.

    With four parameters Express interprets your handler function as an error handler, see more information here: https://expressjs.com/en/guide/error-handling.html. Because of that you get a 404, as the request is passed through the middleware chain into the 404 handler.