CSURF not working - javascript

[Development Env] nodejs v4.2.4 + expressjs v4.13.1 + csurf v1.8.3
I successfully installed csurf middleware but It seems like not working.
I tried submitting form without csrf input field to test it works and there was nothing err. So I inserted console.log codes into router js file
console.log(res.locals._csrf);
and I recieved 'undefined'.
I inserted input field to verify the value exist, html result also had not csrfToken
<input name="_csrf" value="" type="hidden">
What can I do? This is html source
<form class="form" method="post" action="/login" role="form">
<input type="hidden" name="_csrf" value="{{_csrf}}">
<div class="form-group label-floating">
<label class="control-label" for="focusedInput1">User Name</label>
<input class="form-control" name="userName" id="focusedInput1" type="text">
</div>
<div class="form-group">
<div class="form-group label-floating">
<label class="control-label" for="focusedInput2">password</label>
<input class="form-control" name="user_pw" id="focusedInput2" type="password">
</div>
</div>
<div class="form-group">
<button type="submit" class="btn btn-primary" style="float:left">Login</button>
<button type="button" class="btn btn-default" style="float:right" data-dismiss="modal">Cancel</button>
</div>
</form>
and This is app.js
// module importing
var express = require('express'),
path = require('path'),
favicon = require('serve-favicon'),
logger = require('morgan'),
cookieParser = require('cookie-parser'),
bodyParser = require('body-parser'),
exphbs = require('express-handlebars'),
mongoose = require('mongoose'),
csrf = require('csurf');
const session = require('express-session');
const MongoStore = require('connect-mongo')(session);
var routes = require('./routes/index');
var users = require('./routes/users');
var credentials = require('./credentials.js');
var app = express();
// mongoose Setup
mongoose.connect(credentials.mongooseRsrc.collUrl);
// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.engine('.hbs', exphbs({defaultLayout: 'single', extname: '.hbs'}));
app.set('view engine', '.hbs');
// uncomment after placing your favicon in /public
//app.use(favicon(path.join(__dirname, 'public', 'favicon.ico')));
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
app.use(cookieParser(credentials.cookieSecret));
app.use(session({
resave: false,
saveUninitialized: false,
secret: 'sfbsesc',
store: new MongoStore({
mongooseConnection: mongoose.connection
})
}));
app.use(express.static(path.join(__dirname, 'public')));
app.use('/', routes);
app.use('/users', users);
app.use(csrf());
app.use(function(req, res, next){
res.locals._csrf = req.csrfToken();
});
//skip

I had the same issue and worked around it by passing the token in through the controller.
In your routes controller, for your POST /login, pass in the token as an object on response.
router.post('/login', (req, res) => {
res.render('login', {
_csrfToken: req.csrfToken(),
});
});
This could cause issues with other routes depending on how they're set up, but if you encounter errors saying token is invalid, you probably just need to pass it into that route as well

Related

Req.body returns undefined

req.body returns undefined in this part
res.send("Texto "+req.body.titulo+" Conteudo "+req.body.conteudo)
the result is Texto undefined Conteudo undefined
Why is this happening?
I tried using app.use(bodyParser.urlencoded({ extended: false })) app.use(bodyParser.json()) instead of expres, but bodyParser is deprecated.
index.js:
const express = require('express');
const app = express();
const handlebars = require('express-handlebars');
const bodyParser = require('body-parser');
const Post = require('./models/Post');
// Config
// Template Engine
app.engine('handlebars', handlebars({defaultLayout: 'main'}));
app.set('view engine', 'handlebars');
// Body Parser
app.use(express.json({limit:'20mb'}));
app.use(express.urlencoded({extended:false, limit:'20mb'}));
// Rotas
app.get('/cad', function(req, res){
res.render('formularios');
});
app.post('/add', function(req, res){
res.send("Texto "+req.body.titulo+" Conteudo "+req.body.conteudo);
});
app.listen(8081, function(){
console.log("Servidor rodando na URL http://localhost:8081");
});
here is the code that posts to /add. formularios.handlebars:
<form action="/add" method="post">
<div>
<label for="titulo">Título:</label>
<input type="text" name="titulo" id="titulo_id">
</div>
<div>
<label for="conteudo">Conteúdo:</label>
<input type="text" name="conteudo" id="conteudo_id">
</div>
<div class="button">
<button type="submit">Cadastrar postagem</button>
</div>
</form>

Can´t use data from a textarea and make an update Mongodb Express.js

I'm building a simple notes app using express and MongoDB and I got this kind of bug where I can't update the description of the Notes, just the Title. This the form from where I'm getting the data:
<div class="col-md-4 mx-auto">
<div class="card">
<div class="card-header">
<h3>Edit Note</h3>
</div>
<div class="card-body">
<form action="/notes/edit-note/{{note._id}}?_method=PUT" method="POST" >
<input type="hidden" name="_method" value="PUT">
<div class="form-group">
<input type="text " class="form-control" placeholder="title" name="title" value="{{note.title}}">
</div>
<div class="form-group">
<textarea name="decription" id="decription" style="width: 100%;" class="mt-4"placeholder="description">{{note.description}}</textarea>
</div>
<div class="form-group">
<button class="btn btn-primary btn-block" type="submit">Save</button>
</div>
</form>
</div>
</div>
I think thats working fine cause when I console.log(req.body) I get the following:
{ _method: 'PUT', title: 'some text', decription: 'some text' }
Based on this I think the error might be on the JS
My Index.js is the following:
const express = require("express");
const exphbs = require("express-handlebars");
const path = require("path");
const methodOverride = require("method-override");
const session = require("express-session");
const bodyParser = require('body-parser');
//init
const app = express();
require("./database");
//settings
app.set("port", 3000);
app.set("views", path.join(__dirname, "views"));
app.engine(
".hbs",
exphbs({
defaultLayout: "main",
layoutsDir: path.join(app.get("views"), "layouts"),
partialsDir: path.join(app.get("views"), "partials"),
extname: ".hbs",
})
);
app.set("view engine", ".hbs");
//Middleware
app.set(express.urlencoded({ extended: false }));
app.use(bodyParser.urlencoded({extended:true}))
app.use(methodOverride("_method"));
app.use(
session({
secret: "mysecretapp",
resave: true,
saveUninitialized: true,
})
);
//Global varaibles
//routes
app.use(require("./routes/index"));
app.use(require("./routes/notes"));
app.use(require("./routes/users"));
//Static files
app.use(express.static(path.join(__dirname, "public")));
//Server listening
app.listen(app.get("port"), () => console.log("App listening on port 3000!"));
My Schema is the following:
const mongoose=require('mongoose')
const {Schema} = mongoose;
const NoteSchema=new Schema({
title:{type: String, required:true},
description:{type: String, required:true},
date:{type: Date,default:Date.now},
})
module.exports= mongoose.model('Note',NoteSchema)
finally this is the code for the oruter from where in tryin to make the update
const express = require("express");
const router = express.Router();
const Note = require("../models/Note");
router.put("/notes/edit-note/:id", async (req, res) => {
console.log(req.body);
const title = req.body.title;
const description = req.body.description;
await Note.findOneAndUpdate(
{ _id: req.params.id },
{ '$set': { title: title, description: description } }
);
res.redirect("/notes/notes");
});
module.exports = router;
Found the error on
<textarea name="decription" id="decription" style="width: 100%;" class="mt-4"placeholder="description">{{note.description}}</textarea>
name should be 'description', that fixed the problem.

req.body undefined or empty

I have to two controllers and two separate routers.
bookController.js is work perfectly. Now I created userControllers to handle registration and login logic but req.body is empty. I tried to console.log to see if the form is being passed. but I get empty or undefined
I don't know what I am doing or what I have done wrong
Thanks
This is the app.js
var createError = require('http-errors');
var express = require('express');
var path = require('path');
//const csurf = require('csurf');
var cookieParser = require('cookie-parser');
var logger = require('morgan');
var methodOverride = require('method-override')
//const multer = require('multer');
var indexRouter = require('./routes/index');
var usersRouter = require('./routes/users');
var bookRouter = require('./routes/book');
//Cross site request forgery
//const csrfMiddleware = csurf({cookie: true});
var app = express();
// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'ejs');
app.use(logger('dev'));
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
app.use(cookieParser());
//app.use(csrfMiddleware);
app.use(methodOverride('_method'))
//app.use(multerConfig );
app.use(express.static(path.join(__dirname, 'public')));
app.use('/', indexRouter);
app.use('/users', usersRouter);
app.use('/', bookRouter);
// catch 404 and forward to error handler
app.use(function(req, res, next) {
next(createError(404));
});
// 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');
});
module.exports = app;
usersControllers.js
const knex = require('../model/connection');
exports.register = function(req, res)
{
//REGISTER USER FORM PAGE
res.render('user/register');
}
exports.registeruser = function(req, res, next)
{
//REGISTER USER HANDLE
console.log(req.body.username);
console.log(req.body.email);
console.log(req.body.password);
console.log(req.body.password1);
res.render('user/dashboard');
}
and this is routes/users.js
var express = require('express');
var router = express.Router();
var usersControllers = require('../controllers/usersControllers');
/* GET users listing. */
router.get('/dashboard', usersControllers.index);
router.get('/register', usersControllers.register);
router.get('/login', usersControllers.login);
router.post('/registeruser', usersControllers.registeruser);
module.exports = router;
This is the form
<%- include('../includes/layout'); %>
<div class="container">
<div class="row">
<div class="col-lg-3"></div>
<div class="col-lg-6">
<div class="card">
<div class="card-header bg-primary"> Create User </div>
<form id="c_form-h" class="" method="post" action="/users/registeruser" enctype="multipart/form-data" style="padding: 5px;">
<div class="form-group row">
<label for="username" class="col-6 col-form-label">Username</label>
<div class="col-12">
<input type="text" class="form-control" name="username" placeholder="Add UserName">
</div>
</div>
<div class="form-group row">
<label for="email" class="col-6 col-form-label">Email</label>
<div class="col-12">
<input type="email" class="form-control" name="email" placeholder="Add Email">
</div>
</div>
<div class="form-group row">
<label for="password" class="col-6 col-form-label">Password</label>
<div class="col-12">
<input type="password" class="form-control" name="password" placeholder="Enter Password">
</div>
</div>
<div class="form-group row">
<label for="password1" class="col-6 col-form-label">Password</label>
<div class="col-12">
<input type="password" class="form-control" name="password1" placeholder="Enter Password Again">
</div>
</div>
<button type="submit" class="btn btn-primary">Submit</button>
</form>
</div>
</div>
<div class="col-lg-3"></div>
</div>
</div>
<%- include('../includes/footer'); %>
Let’s try to keep this least technical.
Let’s say you are sending a html form data to node-js server i.e. you made a request to the server. The server file would receive your request under a request object. Now by logic, if you console log this request object in your server file you should see your form data some where in it, which could be extracted then, but whoa ! you actually don’t !
So, where is our data ? How will we extract it if its not only present in my request.
Simple explanation to this is http sends your form data in bits and pieces which are intended to get assembled as they reach their destination. So how would you extract your data.
Use something called “body-parser” which would do this for you.
body-parser parses your request and converts it into a format from which you can easily extract relevant information that you may need.
First of all require the following in your app.js file.
var bodyParser = require('body-parser')
and add the following line to make it work
app.use(bodyParser.urlencoded({extended: true}));
Short Answer: Although, you have data coming in URL, you've no way to use that data. Use bocy-parser package to fix this issue.
npm install body-parser --save
This installs the body-parser package. What this does is that it binds together the response data sent back so you can actually get to it and use it. Without it, you're just getting data to an endpoint without any way to use it.
Use the body parser like this:
var bodyParser = require("body-parser");
app.use(bodyParser.urlencoded({extended: true}));
Then inside the function where you try to use the data back do something like
console.log(req.body.username);
console.log(req.body.email);
console.log(req.body.password);
console.log(req.body.password1);
I understand you already tried to implement the body-parser as you said above. Try making a separate endpoint for this. Instead of /users/registeruser, try doing this in a separate /registeruser endpoint and see if that works out. If it does, try again with some insight in endpoints setup, if not, comment further.

Cannot POST to a route from and HTML form

I'm building a nodejs/expressjs application and this is my architecture:
+ routes
- candidate.js
- index.js
+ views
- layout.vash
- register.vash
- server.js
in my server.js file, I put this code to manage routes:
var routes = require('./routes/index');
var candidate = require('./routes/candidate');
app.use('/', routes);
app.use('/candidate', candidate);
in candidate.js, all get requests work fine, but there is a problem in post requests, it can't resolve the path: Cannot POST /caregister
server.js
var routes = require('./routes/index');
var candidate = require('./routes/candidate');
var employer = require('./routes/employer');
var app = express();
app.set('view engine', 'vash');
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('/', routes);
app.use('/candidate', candidate);
app.use('/employer', employer);
app.set('port', (process.env.PORT || 3000));
app.listen(app.get('port'), function(){
console.log('server is listening to ' + app.get('port'));
});
routes/index.js
var express = require('express');
var router = express.Router();
router.get('/', function(req, res){
res.render('index');
});
module.exports = router;
routes/candidate.js
var express = require('express');
var router = express.Router();
var Candidate = require("../models/candidate");
router.get('/', function(req, res){
res.render('candidatelogin'); // relative to candidatelogin.vash
});
router.post('/caregister', function(req, res){
var username = req.body.username;
var email = req.body.email;
var password = req.body.password;
var passwordConf = req.body.passwordConf;
console.log(username + " " + email);
});
module.exports = router;
views/candidatelogin.vash
#html.extend('layout', function(model){
#html.block('body', function(model){
<h1>Jobseeker</h>
<div id="register">
<h3>Create new Account</h3>
<form method="post" action="/caregister">
<input type="text" name="username" placeholder="username"><br/><br/>
<input type="text" name="email" placeholder="email"><br/><br/>
<input type="password" name="password" placeholder="password"><br/><br/>
<input type="password" name="passwordConf" placeholder="password confirmation"><br/><br/>
<input type="submit" value="Register">
</form>
</div>
})
})
When using app.use and including a prefix like candidate that means that you should use this prefix to access this route later on.
So your form in candidatelogin.vash should post to /candidate/caregister url:
<div id="register">
<h3>Create new Account</h3>
<form method="post" action="/candidate/caregister">
<input type="text" name="username" placeholder="username"><br/><br/>
<input type="text" name="email" placeholder="email"><br/><br/>
<input type="password" name="password" placeholder="password"><br/><br/>
<input type="password" name="passwordConf" placeholder="password confirmation"><br/><br/>
<input type="submit" value="Register">
</form>
</div>

NodeJS express Post form - action always 404

No matter what link I declare in the action of my form, it always returns an 404 error. if I change the method to get, it doesn't.
I want to use post because i'm trying to get the data from my input fields and post it in my mongedb database:
HTML:
<form class="container-fluid searchContainer" action="/active" method="post">
<div class="col-xs-6">
<div class="form-group">
<label for="businessUnit">Business unit</label>
<input type="text" ng-model="businessUnit" id="businessUnit" name="businessUnit" class="form-control"/>
</div>
<div class="form-group">
<label for="tenderId">Tender ID</label>
<input type="text" name="tenderID" ng-model="tenderId" id="tenderId" class="form-control"/>
</div>
</div>
<div class="col-xs-6">
<div class="form-group">
<label for="tenderDate">Tender Bidding Date</label>
<input type="date" ng-model="tenderDate" name="tenderDate" id="tenderDate" class="form-control"/>
</div>
<div class="form-group">
<label for="therapyArea">Therapy area</label>
<input type="text" ng-model="therapyArea" name="therapyArea" id="therapyArea" class="form-control"/>
</div>
</div>
<div class="col-md-12 text-right">
<input type="submit" id="btnCreate" value="Create" class="btn btn-primary" >
</div>
</form>
JAVASCRIPT:
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 routes = require('./routes/index');
var users = require('./routes/users');
var active = require('./routes/active');
var app = express();
// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'jade');
// uncomment after placing your favicon in /public
//app.use(favicon(path.join(__dirname, 'public', 'favicon.ico')));
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({
extended: true
}));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));
app.use('/', routes);
app.use('/users', users);
app.use('/active', active);
// catch 404 and forward to error handler
app.use(function(req, res, next) {
var err = new Error('Not Found');
err.status = 404;
next(err);
});
// error handlers
// development error handler
// will print stacktrace
if (app.get('env') === 'development') {
app.use(function(err, req, res, next) {
res.status(err.status || 500);
res.render('error', {
message: err.message,
error: err
});
});
}
// production error handler
// no stacktraces leaked to user
app.use(function(err, req, res, next) {
res.status(err.status || 500);
res.render('error', {
message: err.message,
error: {}
});
});
module.exports = app;
var mongoose = require('mongoose');
mongoose.connect('mongodb://localhost/tenders');
var db = mongoose.connection;
db.on('error', function(err) {
console.log('connection error', err);
});
db.once('open', function() {
console.log('connected.');
});
var Schema = new mongoose.Schema({
TenderID: String,
TenderDate: String,
BusinessUnit: String,
TherapyUnit: String
});
var Tender = mongoose.model('Tender', Schema);
app.post('/active', function(req, res) {
new Tender({
TenderID: req.body.tenderID,
TenderDate: req.body.tenderDate,
BusinessUnit: req.body.businessunit,
TherapyUnit: req.body.therapyUnit
}).save(function(err, doc) {
if (err) res.json(err);
else res.send('Succesfully insterted')
})
});
Because you define your 404 route handler before you define app.post('/active'), express evaluates the 404 rule first and returns it. Your POST /active route never gets evaluated. To fix this you need to give Express your POST /active route before your 404 route (which should always be your last route).
Unless you have an equivalent POST /active route defined in the file ./routes/active, the line
app.use('/active', active);
won't fix this problem even though it is evaluated before your 404 route. You can read more about app.use() vs app.get|post|etc() in the express docs.
Express evaluates rules in the order they are passed to it via use() or get|post|delete|etc()
You have defined get route in your server. Try to change the
app.get('/active',function(req,res){
into
app.post('/active',function(req,res){
In this way, you will respond to a post request from the browser.

Categories