Node.js + express : rewrite url path - node.js

I'd like to know if it's possible to rewrite an url with express.
I actually have this code :
var http, express, app;
http = require("http");
express = require("express");
app = express();
app.use(express.json())
app.use(express.urlencoded())
.post("/ajax_login", function (req, res) {
"use strict";
http.get({ host: "localhost", port: 8080, path: "/users/" + req.body.email + "/email" }, function (resp) {
resp.setEncoding("utf8");
resp.on("data", function (data) {
json = JSON.parse(data);
if (json.password.password === sha1(req.body.password)) {
res.render("home.ejs");
} else {
res.render("login.ejs", { email : req.body.email, error : "password is not good" });
}
});
});
})
.get("/login", function (req, res) {
"use strict";
res.render("login.ejs");
})
.listen(3030);
I call /ajax_login from a form :
<form method="post" action="/ajax_login">
<div class="form-group">
<label for="email">Email address</label>
<input type="email" class="form-control" id="email" name="email" />
</div>
<div class="form-group">
<label for="password">Password</label>
<input type="password" class="form-control" id="password" name="password" />
</div>
<button type="submit" class="btn btn-primary">Connection</button>
</form>
The problem is : when I call /ajax_login, after res.render my HTML code on my browser is changed, but the url still /ajax_login.
How I can change this URL ?
I know the javascript solution :
window.history.pushState("", document.title, "/login");
But, I'd like to know if a solution exist from the server.
Thanks

I would add an error to the request locals, redirect to login, and then check if an error exists when rendering the login page.
.post("/ajax_login", function (req, res) {
"use strict";
...
if (password && email IS OK) {
res.locals.errorMSG = "password is not good";
res.redirect("/login"); //redirect vs render
} else {
res.render("home.ejs");
}
})
.get("/login", function (req, res) {
"use strict";
res.render("login.ejs", {error: res.locals.errorMSG || null});
})
res.locals
res.redirect

Related

Body parser returning undefined for req.body request (SIMPLE LOGIN for beginner)

So I installed body parser via
npm i install express body-parser
and I wrote a simple code designed to input a user into an array after they complete a registration form.
but when I console.log the user it returns undefined for both email and password
here is the server code
const express = require('express');
const path = require('path');
const app = express();
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
const PORT = 3000;
var Users = [{"email":"mike#gmail.com", "password":"456"}];
app.get('/', (req, res) => {
res.render('index.ejs')
})
app.get('/Register.ejs', (req, res) => {
res.render('Register.ejs')
})
app.post('/views/Register.ejs', (req, res) =>
{
const newUser = {
email: req.body.email,
password: req.body.password
};
Users.push(newUser);
res.json(req.body.email);
console.log(Users)
}
)
app.listen(PORT);
here is the html for the register page
<h1>Please Register</h1>
<body>
<form action="/views/Register.ejs" method="POST">
<div class="div">
<label for="email">Enter Email</label>
<input type="email" id="email"for="email" id="email" required>
</div>
<div class="div">
<label for="password">Enter new password</label>
<input type="password" for="password" id="password" required>
</div>
<button type="submit"> Register </button>
</form>
</body>
Only installing body-parser is not enough. You have to put them in the code as middleware.
Top of the code use:
var bodyParser = require('body-parser');
and then use the code in somewhere middle of the code:
app.use(bodyParser.json())

Express - POST request pending

I have a form to register users, but post request is not working
I've checked bodyparser, consign includes order, added enctype to form and still do not work
The route is working, cause it calls my controller, but as you can see at console image, it goes to the controller with undefined req, althought url params are defined at devtools
server.js:
const express = require('express');
const consign = require('consign');
const bodyParser = require('body-parser');
const expressValidator = require('express-validator');
const helmet = require('helmet');
const jwt = require('jsonwebtoken');
require('dotenv-safe').load();
const app = express();
app.set('view engine', 'ejs');
app.set('views', './app/paginas');
app.use(express.static('./app/publico/'));
app.use(bodyParser.urlencoded({extended: true}));
app.use(bodyParser.json());
app.use(expressValidator());
consign(/* {cwd: 'app'} */)
.include('config/conectarBD.js')
.then('app/modelos')
.then('app/controles')
.then('app/rotas')
.into(app);
/* consign()
.include('app/rotas')
.then('config/conectarBD.js')
.then('app/modelos')
.then('app/controles')
.into(app); */
console.log('Instância do app criada');
module.exports = app;
form.ejs:
<div class="row" id="form_registro">
<div class="col-sm-6 offset-sm-3 text-center">
<form action="/registrar" method="POST">
<fieldset>
<legend>Registro</legend>
<div class="form-group">
<label for="form-r-email">Nome:</label>
<input type="text" class="form-control" id="nome" name="nome" placeholder="Seu nome">
</div>
<div class="form-group">
<label for="form-r-email">Email:</label>
<input type="email" class="form-control" id="email" name="email"
placeholder="Seu email">
</div>
<div class="form-group">
<label for="form-r-senha">Senha:</label>
<input type="password" class="form-control" id="senha" name="senha"
placeholder="Sua senha">
</div>
<!-- TODO implementar -->
<div class="form-check">
<input type="checkbox" class="form-check-input" id="exampleCheck2">
<label class="form-check-label" for="exampleCheck1">Lembre de mim</label>
</div>
<button type="submit" class="btn btn-success">Registrar</button>
</fieldset>
<div>
Já tem uma conta?
Registrar!
</div>
</form>
</div>
</div>
route login.js:
module.exports = function(application) {
application.get('/login', function(req, res) {
console.log('Rota pegaPaginaLogin');
application.app.controles.login.pegaPaginaLogin(application, req, res);
});
application.post('/admin/logar', function(req, res) {
console.log('Rota /admin/logar');
application.app.controles.login.logaUsuario(application, req, res);
});
application.post('/registrar', function(req, res) {
console.log('Rota registrar');
console.log('req.body >>>' + req.body);
res.status(500).send('testing');
application.app.controles.login.registraUsuario(application, req, res);
});
}
controller registraUsuario:
module.exports.registraUsuario = function (application, req, res) {
console.log('Controller registraUsuario');
console.log('REQ....' + req)
var usuario = req.body;
/** Validação do formulário */
//TODO validar formatos
req.assert('nome', 'Nome é obrigatório').notEmpty();
req.assert('email', 'Email é obrigatório').notEmpty();
req.assert('senha', 'Senha é obrigatório').notEmpty();
var errosValidacao = req.validationErrors();
console.log(errosValidacao);
if (errosValidacao) {
res.render('login', {
validacao: errosValidacao,
usuario: usuario
});
return;
}
/** Conexão com banco */
var conexao = application.config.conectarBD();
var novoUsuario = new application.app.modelos.UsuariosModel(conexao);
novoUsuario.getUsuario(usuario, function (error, result) {
console.log(result);
novoUsuario.novoUsuario(usuario);
});
}
model UsuariosModel:
function UsuariosModel(conexao) {
this._conexao = conexao;
}
/** Se usuário existir, retorna a id_usuario */
UsuariosModel.prototype.getUsuario = function (usuario, callback) {
console.log('Model getUsuario');
this._conexao.query('SELECT id_usuario FROM usuarios WHERE email = "' + usuario.email + ' and senha = "' + usuario.senha + '"');
}
UsuariosModel.prototype.novoUsuario = function (usuario, callback) {
var hoje = Date.now();
this._conexao.query('INSERT INTO usuarios SET ?', usuario, callback);
}
module.exports = function () {
return UsuariosModel;
};
console:
error:
Your server code is not calling response.send.
Replace your code with this to test:
application.post('/registrar', function(req, res) {
console.log('Rota registrar');
console.log('REQ.query....' + req.params.name);
res.status(500).send('testing');
//application.app.controles.login.registraUsuario(application, req, res);
});
In registraUsuario, you need to call send with your response/status code. Yourclient will block until send is called, or a timeout occurs.

Why am I getting a HTTP 400 error?

I found that the 400 HTTP error is something with syntax but I cannot find anything wrong with my syntax, could someone help take a look at it?
<!- My form view-->
<h3>Login</h3>
<form action="/home/login" method="post">
Enter your usernmae: <input type="text" name="user" value=""><br>
Enter your password: <input type="password" name="pwd" value=""><br>
<input type="submit" name="enter" value="Enter">
</form>
//controller added to my app.js
app.use('/home', indexController);
//in router.js
var passport = require('passport');
var LocalStrategy = require('passport-local').Strategy;
router.post('/login', passport.authenticate('local'), function(req, res) {
req.session.save(function (err) {
if (err) {
return next(err);
}
res.redirect('/home/' + req.user.user);
});
});

bodyparser issue NodeJS express POST >" email undefined"

I am trying to store some user information in a MongoDB database.
From the front-end (AngularJS) on localhost:9000 I make a POST to the backend (express on localhost:3000)
I'm getting in the header information all the data, including the email-address.
but in the body email is undefined??
Console from Node server:
Console from Web browser:
I must do something wrong with the body parser?
Front-end:
registration View:
<form ng-submit="submit()" name="register" class="form-signin" novalidate>
<h1 class="form-signin-heading text-muted">Register</h1>
<input name="email" ng-model="email" type="email" class="form-control" placeholder="Email address" required autofocus="" required>
<p class="help-block" ng-show="register.email.$dirty && register.email.$invalid">Please enter a proper email.</p>
<input name="password" ng-model="password" type="password" class="form-control" placeholder="Password" required>
<input name="password_confirm" ng-model="password_confirm" type="password" class="form-control" placeholder="Confirm Password" validate-equals='password' required>
<p class="help-block" ng-show="register.password_confirm.$dirty && register.password_confirm.$invalid">please match the password.</p>
<button ng-disabled="register.$invalid" class="btn btn-lg btn-primary btn-block" type="submit">
Submit
</button>
</form>
Front-end controller:
'use strict';
angular.module('app')
.controller('RegisterCtrl', function ($scope, $http, alert) {
$scope.submit = function() {
var url = 'http://localhost:3000/register';
var user = {
email: $scope.email,
password: $scope.password
};
$http.post(url, user)
.success(function(res){
alert('success', 'OK!', 'You are now registered');
})
.error(function(err) {
alert('warning', 'Opps!', 'Could not register');
});
}
});
Back-end NodeJS express server.
var express = require('express');
var bodyParser = require('body-parser');
var mongoose = require('mongoose');
var app = express();
app.use(bodyParser.json());
//Verbind front-end met backend
app.use(function(req, res, next){
res.header('Access-Control-Allow-Origin', '*');
res.header('Access-Control-Allow-Methods', 'GET, PUT, POST, DELETE');
res.header('Access-Control-Allow-Headers', 'Content-Type, Authorization');
next();
})
//MongoDB userModel
var User = mongoose.model('User', {
email: String,
password: String
});
//Reactie op de FRONT END POST voor REGISTRATIE
app.post('/register', function(req, res){
//emailVerification.s end(req.user.email);
//createSendToken(req.user, res);
var user = req.body;
console.log('req.body**' + req.body);
console.log('req.headers**' +req.headers);
var newUser = new User({
email: user.name,
password: user.password
})
newUser.save(function(err) {
//als goed opgeslagen > send status 200 en json new user
res.status(200).json(newUser);
console.log(newUser);
});
});
//MONGODB CONNECTIE =====================================
mongoose.connect('mongodb://....');
//MONGODB CONNECTIE =====================================
var server = app.listen(3000, function(){
console.log('api listening on ', server.address().port);
})
Thanks for your help.
Try using Dot operator , Change your Template as below,(sample code)
<form class="list" name="loginForm" ng-submit="login(credentials)" novalidate>
<label class="item item-input item-floating-label" for="username">
<span class="input-label">UserName</span>
<input type="text" placeholder="Username" id="username" ng-model="credentials.username">
</label>
<label class="item item-input item-floating-label" for="password">
<span class="input-label">Password</span>
<input type="password" placeholder="password" id="password" ng-model="credentials.password">
</label>
<button class="button button-block button-dark activated" type="submit">Logga in</button>
</form>
And in your Controller,
you get username as
var user = $scope.username;
Please read upon this article about Understanding Scopes
https://github.com/angular/angular.js/wiki/Understanding-Scopes#ngRepeat
Happy Coding
I made a typo in "Back-end NodeJS express server"
var newUser = new User({
email: **user.name,**
password: user.password
})
must be:
var newUser = new User({
email: **user.email,**
password: user.password
})

Express4 and Formidable file upload works until I enable csrf

I am working through Ethan Brown's book "Web Development with Node and Express" and it has been going well until I got to enabling csrf the multipart/form-data upload on the photo upload. I downloaded the full book code from Github, https://github.com/EthanRBrown/web-development-with-node-and-express and that does the same thing, works until csrf is enabled then it errors with:
Error: invalid csrf token
here are the bits of code I think are relevant, /meadowlark.js starting at line 100
app.use(require('cookie-parser')(credentials.cookieSecret));
app.use(require('express-session')({ store: sessionStore,
secret: credentials.cookieSecret,
name: credentials.cookieName,
saveUninitialized: true,
resave: true }));
app.use(express.static(__dirname + '/public'));
app.use(require('body-parser')());
// cross-site request forgery protection
app.use(require('csurf')());
app.use(function(req, res, next){
res.locals._csrfToken = req.csrfToken();
next();
});
// database configuration
var mongoose = require('mongoose');
var options = {
server: {
socketOptions: { keepAlive: 1 }
}
};
Then in /handlers/contest.js
var path = require('path'),
fs = require('fs'),
formidable = require('formidable');
// make sure data directory exists
var dataDir = path.normalize(path.join(__dirname, '..', 'data'));
var vacationPhotoDir = path.join(dataDir, 'vacation-photo');
fs.existsSync(dataDir) || fs.mkdirSync(dataDir);
fs.existsSync(vacationPhotoDir) || fs.mkdirSync(vacationPhotoDir);
exports.vacationPhoto = function(req, res){
var now = new Date();
res.render('contest/vacation-photo', { year: now.getFullYear(), month: now.getMonth() });
};
function saveContestEntry(contestName, email, year, month, photoPath){
// TODO...this will come later
}
exports.vacationPhotoProcessPost = function(req, res){
var form = new formidable.IncomingForm();
form.parse(req, function(err, fields, files){
if(err) return res.redirect(303, '/error');
if(err) {
res.session.flash = {
type: 'danger',
intro: 'Oops!',
message: 'There was an error processing your submission. ' +
'Pelase try again.',
};
return res.redirect(303, '/contest/vacation-photo');
}
var photo = files.photo;
var dir = vacationPhotoDir + '/' + Date.now();
var path = dir + '/' + photo.name;
fs.mkdirSync(dir);
fs.renameSync(photo.path, dir + '/' + photo.name);
saveContestEntry('vacation-photo', fields.email,
req.params.year, req.params.month, path);
req.session.flash = {
type: 'success',
intro: 'Good luck!',
message: 'You have been entered into the contest.',
};
return res.redirect(303, '/contest/vacation-photo/entries');
});
};
exports.vacationPhotoEntries = function(req, res){
res.render('contest/vacation-photo/entries');
};
and the views/contest/vacation-photo.handlebars
<form class="form-horizontal" role="form"
enctype="multipart/form-data" method="POST"
action="/contest/vacation-photo/{{year}}/{{month}}">
<input type="hidden" name="_csrf" value="{{_csrfToken}}">
<div class="form-group">
<label for="fieldName" class="col-sm-2 control-label">Name</label>
<div class="col-sm-4">
<input type="text" class="form-control"
id="fieldName" name="name">
</div>
</div>
<div class="form-group">
<label for="fieldEmail" class="col-sm-2 control-label">Email</label>
<div class="col-sm-4">
<input type="email" class="form-control" required
id="fieldName" name="email">
</div>
</div>
<div class="form-group">
<label for="fieldPhoto" class="col-sm-2 control-label">Vacation photo</label>
<div class="col-sm-4">
<input type="file" class="form-control" required accept="image/*"
id="fieldPhoto" data-url="/upload" name="photo">
</div>
</div>
<div class="form-group">
<div class="col-sm-offset-2 col-sm-4">
<button type="submit" class="btn btn-primary">Submit</button>
</div>
</div>
</form>
What is the proper way to make csrf work?
Thanks,
On vacation-photo GET request, you should send csrf token like below.
exports.vacationPhotoEntries = function(req, res){
res.render('contest/vacation-photo/entries', { _csrfToken: req.csrfToken()});
};
You can also catch csrf token error in your default error handler like below.
// error handler
app.use(function (err, req, res, next) {
if (err.code !== 'EBADCSRFTOKEN') return next(err)
// handle CSRF token errors here
res.status(403)
res.send('session has expired or form tampered with')
})
For more info, please check this link.
Append csrf token as query string to action Url..
It works!
<form class="form-horizontal" role="form" enctype="multipart/form-data" method="POST"
action="/contest/vacation-photo/{{year}}/{{month}}?_csrf={{_csrfToken}}">
</form>

Resources