Why is ExpressJS request body not working - javascript

I am posting here for first time So if anything wrong is with post then please tell me.
I am new to node and express . I have created a simple registration form , but when I press Register(submit) button the I got req.body.name as "undefiend" .
Below I have attached my app.js, users.js and register.jade file.
register.jade
extends layout
block content
h1 Register
p Please Register using a form below
ul.errors
if errors
each error , i in errors
li.alert.alert-danger #{error.msg}
form(method='post',action='/users/register',enctype='multipart/form-data')
.form-group
label Name
input.form-control(name='name',type='text',placeholder='Enter Your Lucky Name')
.form-group
label Email
input.form-control(name='email',type='email',placeholder='Enter Your Email')
.form-group
label Password
input.form-control(name='password',type='password',placeholder='Enter Password')
.form-group
label Confirm Password
input.form-control(name='password2',type='password',placeholder='Enter Password')
.form-group
label Profie Image
input.form-control(name='profileimage',type='file')
input.btn.btn-default(name='submit',type='submit',value='Register')
app.js
var express = require('express');
var path = require('path');
var favicon = require('serve-favicon');
var logger = require('morgan');
var expressValidator=require('express-validator');
var cookieParser = require('cookie-parser');
var session=require('express-session');
var passport=require('passport');
var LocalStartegy=require('passport-local').Strategy;
var bodyParser = require('body-parser');
//var multer=require('multer');
var flash=require('connect-flash');
var mongo=require('mongodb');
var mongoose=require('mongoose');
var db=mongoose.connection;
//var upload=multer({dest:'./uploads'});
var routes = require('./routes/index');
var users = require('./routes/users');
var multer = require('multer');
var upload = multer({ dest: './uploads' });
var app = express();
// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'jade');
//Handle file upload
app.use(multer({dest:'./uploads'}));
// 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: false }));
//Handle express sessions
app.use(session({
secret:'secret',
saveUninitialized:true,
resave:true
}));
//passport
app.use(passport.initialize());
app.use(passport.session());
app.use(expressValidator());
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));
app.use(flash());
app.use(require('connect-flash')());
app.use(function (req, res, next) {
res.locals.messages = require('express-messages')(req, res);
next();
});
app.use('/', routes);
app.use('/users', users);
// 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 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;
users.js
var express = require('express');
var router = express.Router();
var User = require('../models/user');
/* GET users listing. */
router.get('/', function(req, res, next) {
res.send('respond with a resource');
});
/* GET users listing. */
router.get('/register', function(req, res, next) {
res.render('register',{
'title':'Register'
});
});
router.get('/login', function(req, res, next) {
res.render('login',{
'title':'Login '
});
});
router.post('/register',function(req,res,next) {
//Get form Values
var name=req.body.name;
var email=req.body.email;
//var username=req.body.username;
var password=req.body.password;
var password2=req.body.password2;
console.log('hello ' +req.body); //gets hello [object Object]
console.log('hello' + req.body.name); //H=hello undefined
//Check For Image Field
if(req.files.profileimage) {
console.log("uploding file");
var profileImageOriginalName=req.files.profileimage.originalname;
var profileImageName=req.files.profileimage.name;
var profileImageMime=req.files.profileimage.mime;
var profileImagePath=req.files.profileimage.path;
var profileImageExt=req.files.profileimage.extension;
var profileImageSize=req.files.profileimage.size;
} else {
var profileImageName='NoImage.png';
}
//Form Validation
req.checkBody('name','Name Field is Required').notEmpty();
req.checkBody('email','Email Field is Required').notEmpty();
req.checkBody('email','Enter Correct Email').isEmail();
req.checkBody('password','Password Field is Reqired').notEmpty();
req.checkBody('password2','Password Doesn\'t match').equals(req.body.password);
//Check For Errors
var errors = req.validationErrors();
if(errors) {
res.render('register', {
errors:errors,
name:name,
email:email,
username:username,
password:password,
password2:password2
});
} else {
var newUser = new User({
name:name,
email:email,
// username:username,
password:password,
//profileimage:profileImageName
});
User.createUser(newUser,function(err,user){
if(err) throw err;
console.log(user);
});
req.flash('success','You Have Successfulyy Registerd');
res.location('/');
res.redirect('/');
}
});
module.exports = router;

The body property is not a member of Response, it's member of Request. So your code should be correct as follow.
Use console.log('hello ' + req.body); instead of console.log('hello
' + res.body);
var express = require('express');
var router = express.Router();
var User = require('../models/user');
/* GET users listing. */
router.get('/', function (req, res, next) {
res.send('respond with a resource');
});
/* GET users listing. */
router.get('/register', function (req, res, next) {
res.render('register', {
'title': 'Register'
});
});
router.get('/login', function (req, res, next) {
res.render('login', {
'title': 'Login '
});
});
router.post('/register', function (req, res, next) {
//Get form Values
var name = req.body.name;
var email = req.body.email;
//var username=req.body.username;
var password = req.body.password;
var password2 = req.body.password2;
console.log('hello ' + req.body); //gets undefined
//Check For Image Field
if (req.files.profileimage) {
console.log("uploding file");
var profileImageOriginalName = req.files.profileimage.originalname;
var profileImageName = req.files.profileimage.name;
var profileImageMime = req.files.profileimage.mime;
var profileImagePath = req.files.profileimage.path;
var profileImageExt = req.files.profileimage.extension;
var profileImageSize = req.files.profileimage.size;
} else {
var profileImageName = 'NoImage.png';
}
//Form Validation
req.checkBody('name', 'Name Field is Required').notEmpty();
req.checkBody('email', 'Email Field is Required').notEmpty();
req.checkBody('email', 'Enter Correct Email').isEmail();
req.checkBody('password', 'Password Field is Reqired').notEmpty();
req.checkBody('password2', 'Password Doesn\'t match').equals(req.body.password);
//Check For Errors
var errors = req.validationErrors();
if (errors) {
res.render('register', {
errors: errors,
name: name,
email: email,
username: username,
password: password,
password2: password2
});
} else {
var newUser = new User({
name: name,
email: email,
// username:username,
password: password,
//profileimage:profileImageName
});
User.createUser(newUser, function (err, user) {
if (err) throw err;
console.log(user);
});
req.flash('success', 'You Have Successfulyy Registerd');
res.location('/');
res.redirect('/');
}
});
module.exports = router;

That's because you're not using multer properly.
// Declare
var upload = multer({ dest: 'uploads/' })
...
/**
* Use multer as the middleware for this route. This is should parse multipart/form-data encoding
* and pick up the uploaded image file and assign to req.file.
**/
router.post('/register', upload.single('profileimage), function (req, res, next) {
console.log(req.file); // you will see fields related to your uploaded file.
console.log(req.body); // you will see your form fields
...
})
...

First, try without file in your form remove enctype attribute from your form element
enctype='multipart/form-data'
where your body-parser must work and then you will get request data in req.body property.
if you intend to use enctype with file uploading via form,
you have to configure your multer correctly, place this code in users.js file
var multer = require('multer');
var upload = multer({ dest: './uploads' }); // make sure you have uploads folder
//(I would recommend using disk storage for complete control over uploaded files).
and when you are handling your post request
router.post('/register', upload.single('field_name'), function(req,res,next){
//req.body will have text data
// req.file will have file uploaded via form.
});
// make sure what ever you have name attribute value in from file input
// use that instead of <filed_name>. in your case 'profileimage'.
now multer will parse your incoming data and as we used uplaod.single() file will be availabel in
req.file
and if you used uplaod.array() file will be availabel in
req.files
and all the text field value will be in
req.body

Related

Node.js - user Authentication with Passport (Learn Node.js by building 10 projects course)

I'm following a tutorial which probably is outdated in some moments, but anyway I would like to finish it.
Here is the problem - I stacked on user Authentication with Passport and can't Login into my website though there are no mistakes in my code and even in console (what is the most terrible part cuz I can't see what actually is wrong). After clicking button "submit" it must redirect me to members area page but it simply doesn't respond. And no errors on console, like everything is working fine! I'm sorry if I did or said something wrong, it's my first question here :) And thank you for any help or advice! Here are my code snippets:
// In app.js:
var express = require('express');
var path = require('path');
var favicon = require('serve-favicon');
var logger = require('morgan');
var expressValidator = require('express-validator');
var cookieParser = require('cookie-parser');
var session = require('express-session');
var passport = require('passport');
var LocalStrategy = require('passport-local').Strategy;
var bodyParser = require('body-parser');
var multer = require('multer');
var uploads = multer({dest: './uploads'});
var flash = require('connect-flash');
var mongo = require('mongodb');
var mongoose = require('mongoose');
var db = mongoose.connection;
var routes = require('./routes/index');
var users = require('./routes/users');
var app = express();
// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'jade');
// Handle file uploads
var upload = multer({ dest: './uploads' });
// 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: false }));
// Handle Express Sessions
app.use(session({
secret:'secret',
saveUninitialized: true,
resave: true
}));
// passport
app.use(passport.initialize());
app.use(passport.session());
// Validator
app.use(expressValidator({
errorFormatter: function(param, msg, value) {
var namespace = param.split('.')
, root = namespace.shift()
, formParam = root;
while(namespace.length) {
formParam += '[' + namespace.shift() + ']';
}
return {
param : formParam,
msg : msg,
value : value
};
}
}));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));
app.use(flash());
app.use(function (req, res, next) {
res.locals.messages = require('express-messages')(req, res);
next();
});
app.get('*', function(req, res, next){
res.locals.user = req.user || null;
next();
});
app.use('/', routes);
app.use('/users', users);
// 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);
<!-- begin snippet: js hide: false console: true babel: false -->
// In users.js in routes:
var express = require('express');
var router = express.Router();
var passport = require('passport');
var LocalStrategy = require('passport-local').Strategy;
var User = require('../models/user');
var multer = require('multer');
var uploads = multer({dest: './uploads'});
/* GET users listing. */
router.get('/', function(req, res, next) {
res.send('respond with a resource');
});
router.get('/register', function(req, res, next) {
res.render('register', {
'title': 'Register'
});
});
router.get('/login', function(req, res, next) {
res.render('login', {
'title': 'Login'
});
});
router.post('/register', uploads.single('profileimage'), function(req, res, next) {
var name = req.body.name;
var email = req.body.email;
var username = req.body.username;
var password = req.body.password;
var password2 = req.body.password2;
// Check for Image Field
if (req.file) {
console.log('uploading File...');
// File Info
var profileImageOriginalName = req.files.profileimage.originalname;
var profileImageName = req.files.profileimage.name;
var profileImageMime = req.files.profileimage.mimetype;
var profileImagePath = req.files.profileimage.path;
var profileImageExt = req.files.profileimage.extension;
var profileImageSize = req.files.profileimage.size;
} else {
// Set a Default Image
var profileImageName = 'noimage.png';
}
// Form Validation
req.checkBody('name','Name field is required').notEmpty();
req.checkBody('email','Email field is required').notEmpty();
req.checkBody('email','Email not valid').isEmail();
req.checkBody('username','Username field is required').notEmpty();
req.checkBody('password','Password field is required').notEmpty();
req.checkBody('password2','Password do not match').equals(req.body.password);
// Check for errors
var errors = req.validationErrors();
if(errors){
res.render('register', {
errors: errors,
name: name,
email: email,
username: username,
password: password,
password2: password2
});
} else {
var newUser = new User({
name: name,
email: email,
username: username,
password: password,
profileImage: profileImageName
});
// Create User
User.createUser(newUser, function(err, user){
if(err)throw err;
console.log(user);
});
//Success Message
req.flash('success', 'You are now registered and may log in');
res.location('/');
res.redirect('/');
}
});
passport.serializeUser(function(user, done) {
done(null, user.id);
});
passport.deserializeUser(function(id, done) {
User.getUserById(id, function(err, user) {
done(err, user);
});
});
passport.use(new LocalStrategy(
function(username, password, done){
User.getUserByUsername(username, function(err, user){
if(err) throw err;
if(!user){
console.log('Unknown User');
return done(null, false, {message: 'Unknown User'});
}
User.comparePassword(password, user.password, function(err, isMatch){
if(err) throw err;
if(isMatch){
return done(null, user);
} else {
console.log('Invalid Password');
return done(null, false, {message: 'Invalid Password'});
}
});
});
}
));
router.post('/login', passport.authenticate('local',{failureRedirect: '/users/login', failureFlash: 'Invalid username or password'}), function(req, res){
console.log('Authentication Successful');
req.flash('success', 'You are logged in');
res.redirect('/');
});
router.get('/logout', function(req, res){
req.logout();
req.flash('success', 'You have logged out');
res.redirect('/users/login');
});
module.exports = router;
res.render('error', {
message: err.message,
error: {}
});
});
module.exports = app;
<!-- end snippet -->
// In package.json:
{
"name": "nodeauth",
"version": "1.0.0",
"private": true,
"scripts": {
"start": "node ./bin/www"
},
"dependencies": {
"body-parser": "~1.15.1",
"cookie-parser": "~1.4.3",
"debug": "~2.2.0",
"express": "~4.13.4",
"jade": "~1.11.0",
"morgan": "~1.7.0",
"serve-favicon": "~2.3.0",
"mongodb":"*",
"mongoose":"*",
"connect-flash":"*",
"express-validator":"*",
"express-session":"*",
"express-messages":"*",
"passport":"*",
"passport-local":"*",
"passport-http":"*",
"multer":"*"
}
}
// In user.js in models:
var mongoose = require('mongoose');
var bcrypt = require('bcrypt');
mongoose.connect('mongodb://localhost/nodeauth');
var db = mongoose.connection;
// User Schema
var UserSchema = mongoose.Schema({
username: {
type: String,
index: true
},
password: {
type: String,
required: true,
bcrypt: true
},
email: {
type: String
},
name: {
type: String
},
profileimage: {
type: String
}
});
var User = module.exports = mongoose.model('User', UserSchema);
module.exports.comparePassword = function(candidatePassowrd, hash, callback){
bcrypt.compare(candidatePassowrd, hash, function(err, isMatch){
if(err) return callback(err);
callback(null, isMatch);
});
}
module.exports.getUserById = function(id, callback){
User.findById(id, callback);
}
module.exports.getUserByUsername = function(username, callback){
var query = {username: username};
User.findOne(query, callback);
}
module.exports.createUser = function(newUser,callback){
bcrypt.hash(newUser.password, 10, function(err, hash){
if(err) throw err;
// Set Hashed password
newUser.password = hash;
// Create User
newUser.save(callback);
});
};
I encountered the same issue. The problem is the form. Remove the enctype part and it works!
Edit: The reason why removing the enctype caused it to work is because then it does not need Multer. Multer's API changed since this was recorded. You need to include uploads.single('profileimage') as the second param in the post.
Please remember to define the require for multer in the new way as well.
Example:
var multer = require('multer');
// To handle the inclusion of the extension in the filename
var path = require('path')
var storage = multer.diskStorage({
destination: function (req, file, callback) {
callback(null, './public/images/uploads')
},
filename: function (req, file, callback) {
callback(null, Date.now() + path.extname(file.originalname)) //Appending extension
}
})
var upload = multer({ storage: storage });
The above example was taken from the next project in the course that required an upload of an image. It was only when hitting this project that I was able to find the required workaround to make it work as its supposed it. Reading the documentation on multer helped as well.

uploading file to folder in node-express site using multer with mongodb

I have a node-express app that authenticates user data and upload files using multer, when i click on submit, the name, email, username and password fields are stored in the mongodb database. But the profileimage file is not stored in the uploads folder nor stored by monogdb. I tried using some help i found online but all worked with my app but did not store the picture in the folder nor did mongodb pass the profileimage field in the cli as expected by the model i used. Please What am I not getting right here, that's stopping the file from being uploaded and stored in the required folder and the name of the file being displayed in the mongodb cli?
Note: Other codes that worked fine with my app are commented in the below code sample but none stored the picture in the desired folder.
users.js
var express = require('express');
var router = express.Router();
var multer = require('multer');
var uploads = multer({dest: './uploads/'});
/*var storage = multer.diskStorage({
destination: function (req, file, cb) {
cb(null, './uploads/');
},
filename: function (req, file, cb) {
var originalname = file.originalname;
var extension = originalname.split(".");
filename = Date.now() + '.' + extension[extension.length-1];
cb(null, filename);
}
}); */
//Require a model page
var User = require('../models/user');
/* GET users listing. */
router.get('/', function(req, res, next) {
res.send('respond with a resource');
});
router.get('/register', function(req, res, next) {
res.render('register', {
'title': 'Register'
});
});
router.get('/login', function(req, res, next) {
res.render('login', {
'title': 'Log In'
});
});
//router.post('/register', multer({storage: storage, dest: './uploads/'}).single('profileimage'), function(req,res){
router.post('/register', uploads.single('profileimage'), function(req,res,next){
//Get Form Value
var name = req.body.name;
var email = req.body.email;
var username = req.body.username;
var password = req.body.password;
var password2 = req.body.password2;
//Check for Image field
if(req.file){
console.log('uploading File...');
// File Info
var profileImageOriginalName = req.files.profileimage.originalname;
var profileImageName = req.files.profileimage.name;
var profileImageMime = req.files.profileimage.mimetype;
var profileImagePath = req.files.profileimage.path;
var profileImageExt = req.files.profileimage.extension;
var profileImageSize = req.files.profileimage.size;
} else {
// Set a Default Image
var profileImageName = 'noimage.png';
}
/*if(req.file){
console.log('uploading File...');
// File Info
originalname = req.files.profileimage.originalname;
feildname = req.files.profileimage.fieldname;
mimetype = req.files.profileimage.mimetype;
path = req.files.profileimage.path;
encoding = req.files.profileimage.encoding;
size = req.files.profileimage.size;
} else {
// Set a Default Image
var original = 'noimage.png';
} */
//Form Validation
req.checkBody('name', 'Name Field is required').notEmpty();
req.checkBody('email', 'Email Field is required').notEmpty();
req.checkBody('email', 'Email not valid').isEmail();
req.checkBody('username', 'Username Field is required').notEmpty();
req.checkBody('password', 'Password Field is required').notEmpty();
req.checkBody('password2', 'Passwords do not match').equals(req.body.password);
//Check for Errors
var errors = req.validationErrors();
if(errors){
res.render('register',{
errors: errors,
name: name,
email: email,
username: username,
password: password,
password2: password2
});
} else {
var newUser = new User({
name: name,
email: email,
username: username,
password: password,
profileImage: profileImageName
});
//Create User
User.createUser(newUser, function (err, user) {
if(err) throw err;
console.log(user);
});
//Success Message
req.flash('success', 'You are now registered and may Log in');
res.location('/');
res.redirect('/');
}
});
module.exports = router;
app.js
var express = require('express');
var path = require('path');
var favicon = require('serve-favicon');
var logger = require('morgan');
var expressValidator = require('express-validator');
var cookieParser = require('cookie-parser');
var session = require('express-session');
var passport = require('passport');
var LocalStrategy = require('passport-local').Strategy;
var bodyParser = require('body-parser');
//var multer = require('multer');
var flash = require('connect-flash');
var mongo = require('mongodb');
var mongoose = require('mongoose');
var db = mongoose.connection;
var multer = require('multer');
var routes = require('./routes/index');
var users = require('./routes/users');
var app = express();
// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'jade');
//Handle File Uploads
var upload = multer({ dest: './uploads' });
// 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: false }));
//Handle Express Sessions
app.use(session({
secret:'secret',
saveUninitialized: true,
resave: true
}));
//Passport
app.use(passport.initialize());
app.use(passport.session());
// Validator
app.use(expressValidator({
errorFormatter: function(param, msg, value) {
var namespace = param.split('.')
, root = namespace.shift()
, formParam = root;
while(namespace.length) {
formParam += '[' + namespace.shift() + ']';
}
return {
param : formParam,
msg : msg,
value : value
};
}
}));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));
app.use(flash());
app.use(function (req, res, next) {
res.locals.messages = require('express-messages')(req, res);
next();
});
app.use('/', routes);
app.use('/users', users);
// 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;
models/user.js
var mongoose = require('mongoose');
//This chooses the database to use for storing data a very important step
mongoose.connect('mongodb://localhost/nodeauth');
var db = mongoose.connection;
//User Schema
var UserSchema = mongoose.Schema({
username: {
type: String,
index: true
},
password: {
type: String
},
email: {
type: String
},
name: {
type: String
},
profileimaage: {
type: String
}
});
var User = module.exports = mongoose.model('User', UserSchema);
module.exports.createUser = function (newUser, callback) {
newUser.save(callback);
}
create multerhelper.js file in your app nd add below code in it
const multer = require('multer');
// const fs = require('fs');
let fs = require('fs-extra');
let storage = multer.diskStorage({
destination: function (req, file, cb) {
let Id = req.body.id;
let path = `tmp/daily_gasoline_report/${Id}`;
fs.mkdirsSync(path);
cb(null, path);
},
filename: function (req, file, cb) {
// console.log(file);
let extArray = file.mimetype.split("/");
let extension = extArray[extArray.length - 1];
cb(null, file.fieldname + '-' + Date.now() + "." + extension);
}
})
var upload = multer({ storage: storage });
let createUserImage = upload.single('images');
let multerHelper = {
createUserImage,
}
module.exports = multerHelper;
in your user.js file import this file
const multerhelper = require("../multerhelper.js");
router.post('/register',multerhelper , function(req,res,next){
Here you are just loading the multer module not using anywhere.
Check the link for full uses :
https://github.com/expressjs/multer

Node.js Passport Display username after successful login

I am using Node.js Passport and I'm trying to figure out how to display username after a successful login. After reading the documentation I've verified that i have Sessions and Middleware configured which is what I need but what are my next steps?
This is my users.js file:
var express = require('express');
var router = express.Router();
var passport = require('passport');
var LocalStrategy = require('passport-local').Strategy;
var User = require('../models/user');
// Home
router.get('/index', function(req, res){
res.render('index');
});
// Profile
router.get('/profile', function(req, res){
res.render('profile');
});
// Register
router.get('/register', function(req, res){
res.render('register');
});
// Login
router.get('/login', function(req, res){
res.render('login');
});
// About-us
router.get('/about-us', function(req, res){
res.render('about-us');
});
// Register User
router.post('/register', function(req, res){
var email = req.body.email;
var username = req.body.username;
var password = req.body.password;
// Validation
req.checkBody('username', 'Username is Required').notEmpty();
req.checkBody('email', 'Email is required').notEmpty();
req.checkBody('email', 'Email is not valid').isEmail();
req.checkBody('password', 'Password is required').notEmpty();
var errors = req.validationErrors();
if(errors){
res.render('register',{
errors:errors
});
} else {
var newUser = new User({
email:email,
username: username,
password: password,
});
User.createUser(newUser, function(err, user){
if(err) throw err;
console.log(user);
});
req.flash('success_msg', 'You are now registered. Log In!');
res.redirect('/users/login');
}
});
passport.use(new LocalStrategy(
function(username, password, done) {
User.getUserByUsername(username, function(err, user){
if(err) throw err;
if(!user){
return done(null, false, {message: 'User does not exist!'});
}
User.comparePassword(password, user.password, function(err, isMatch){
if(err) throw err;
if(isMatch){
return done(null, user);
} else {
return done(null, false, {message: 'Invalid password'});
}
});
});
}));
passport.serializeUser(function(user, done) {
done(null, user.id);
});
passport.deserializeUser(function(id, done) {
User.getUserById(id, function(err, user) {
done(err, user);
});
});
router.post('/login',
passport.authenticate('local', {successRedirect:'/users/profile', failureRedirect:'/users/login',failureFlash: true}),
function(req, res) {
res.redirect('/users/profile')
});
router.get('/logout', function(req, res){
req.logout();
req.flash('success_msg', '');
res.redirect('/');
});
module.exports = router;
And this is my app.js file:
var express = require('express');
var path = require('path');
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');
var exphbs = require('express-handlebars');
var expressValidator = require('express-validator');
var flash = require('connect-flash');
var session = require('express-session');
var passport = require('passport');
var LocalStrategy = require('passport-local').Strategy;
var mongo = require('mongodb');
var mongoose = require('mongoose');
mongoose.connect('mongodb://localhost/loginandregister');
var db = mongoose.connection;
var routes = require('./routes/index');
var users = require('./routes/users');
// Init App
var app = express();
// View Engine
app.set('views', path.join(__dirname, 'views'));
app.engine('handlebars', exphbs({defaultLayout:'layout'}));
app.set('view engine', 'handlebars');
// BodyParser Middleware
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(cookieParser());
// Set Static Folder
app.use(express.static(path.join(__dirname, 'public')));
app.use('/public', express.static('public'));
// Express Session
app.use(session({
secret: 'secret',
saveUninitialized: true,
resave: true
}));
// Passport init
app.use(passport.initialize());
app.use(passport.session());
// Express Validator
app.use(expressValidator({
errorFormatter: function(param, msg, value) {
var namespace = param.split('.')
, root = namespace.shift()
, formParam = root;
while(namespace.length) {
formParam += '[' + namespace.shift() + ']';
}
return {
param : formParam,
msg : msg,
value : value
};
}
}));
// Connect Flash
app.use(flash());
// Global Vars
app.use(function (req, res, next) {
res.locals.success_msg = req.flash('success_msg');
res.locals.error_msg = req.flash('error_msg');
res.locals.error = req.flash('error');
res.locals.user = req.user || null;
next();
});
app.use('/', routes);
app.use('/users', users);
// Set Port
app.set('port', (process.env.PORT || 3000));
app.listen(app.get('port'), function(){
console.log('Server started on port '+app.get('port'));
});
I've read a similar question on the site and the answer stated that:
app.get('/example', function(req, res) {
res.render('index', { username: req.user.username });
});
needs to be implemented. But I am confused as to where and how? I tried placing it into to my users.js file but i get a "ReferenceError: app is not defined" error in terminal when restarting the node app.
What are my next steps? Any and every help is valued and appreciated. Thank you.
EDIT:
I added
router.get('/profile', function(req, res){
res.render('profile', { username: req.user.username });
});
to my users.js file and added:
<header>
<h1>Hello?</h1>
{{#if user}}
<p>Hello {{username}}</p>
{{else}}
<p>Please <a href='/users/login'>Log In</a></p>
{{/if}}
</header>
to my profile.handlebars page but still no username display. What am i missing???
SOLUTION: Apparently my code was correct and my problem was solved hours ago however it was hiding in plain site. I am using Firefox to build my site and Chrome to conduct all my research and web searching. After DEEP searching i stumbled upon another similar question to my own and this guy complained that he had <p>Hi, {{username}}</p> within his index file but only Hi was showing up within his browser. On the contrary neither Hi or {{username}} was showing in my browser. My entire <p> tag was missing. So i simply loaded my site in Chrome and there it was problem solved! Bad practice on my part for only using one browser but that's what I get for silly mistakes :)
You need to use the rendering part of the mentioned part of this code:
app.get('/example', function(req, res) {
res.render('index', { username: req.user.username });
});
i.e., res.render('index', { username: req.user.username }); at the right/required path.
like you can try using it as
router.get('/profile', function(req, res){
res.render('profile', { username: req.user.username });
});
and consume(use) the rendered variable username in your view for displaying.
If this doesn't work or you have some other problem, refer Nodejs Passport display username also.
My workaround was adding the req.user (if it exists, thus when loggedin) to the rendering. I've included both a hello, {{user}} and Dynamic navbar example.
I don't know if it's because I use handlebars instead of express-handelbars but the example I used to make this does not have to send the req.user object along for the render. It automatically sends it along? So I feel like my workaround is unnecesary if I do it right?
Edit: this solution only works for 1 page. If you go to another route it doesn't send the object along anymore.
Edit2: Apparently with express 4 sending the user object along in req.user is the only way I've found so far. But you'll have to send it along every route that requests data from the data base as well.
Confirmed edit 2 through this example: https://github.com/passport/express-4.x-local-example/blob/master/server.js
// Get Homepage
router.get('/', function(req,res){
Job.find({})
.exec(function(err, jobs){
if(err){
res.send('Error occured', err);
} else {
res.render('jobs', {jobs, user:req.user});
}
});
});
<nav>
<ul class="nav nav-pills pull-right">
{{#if user}}
<li role="presentation"><span class="glyphicons glyphicons-user"></span><p style='color:white'>Hello {{user.name}}</p></li>
<li role="presentation">Logout</li>
{{else}}
<li role="presentation">Login</li>
<li role="presentation">Register</li>
{{/if}}
</ul>
</nav>

Passport-init.js authentication is not working in nodejs

I am new to nodejs and trying to develop nodejs demo application referring this article. I followed all steps
and its first phase is working fine for me. But after adding passport authentication it is not working
here is my 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 session = require('express-session');
var passport = require('passport');
//add for Mongo support
//var mongoose = require('mongoose');
var api = require('./routes/api');
var authenticate = require('./routes/authenticate')(passport);
//connect to Mongo
// mongoose.connect('mongodb://localhost:27017/MEAN_Stack');
// require('./models/models.js');
var app = express();
// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'ejs');
// uncomment after placing your favicon in /public
//app.use(favicon(path.join(__dirname, 'public', 'favicon.ico')));
app.use(logger('dev'));
app.use(session({
secret: 'keyboard cat'
}));
//app.use(bodyParser.json());
//app.use(bodyParser.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));
app.use(passport.initialize());
app.use(passport.session());
//// Initialize Passport
var initPassport = require('./passport-init');
initPassport(passport);
app.use('/api', api);
app.use('/auth', authenticate);
// 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;
here is my api.js
var express = require('express');
var router = express.Router();
//Register the authentication middleware
//router.use('/posts');
//api for all posts
router.route('/posts')
//create a new post
.post(function(req, res){
//TODO create a new post in the database
res.send({message:"TODO create a new post in the database rhushikesh"});
})
.get(function(req, res){
//TODO get all the posts in the database
res.send({message:"TODO get all the posts in the database"});
})
//api for a specfic post
router.route('/posts/:id')
//create
.put(function(req,res){
return res.send({message:'TODO modify an existing post by using param ' + req.param.id});
})
.get(function(req,res){
return res.send({message:'TODO get an existing post by using param ' + req.param.id});
})
.delete(function(req,res){
return res.send({message:'TODO delete an existing post by using param ' + req.param.id})
});
module.exports = router;
here is my authenticate.js
var express = require('express');
var router = express.Router();
module.exports = function(passport){
//sends successful login state back to angular
router.get('/success', function(req, res){
res.send({state: 'success', user: req.user ? req.user : null});
});
//sends failure login state back to angular
router.get('/failure', function(req, res){
res.send({state: 'failure', user: null, message: "Invalid username or password1111"});
});
//log in
router.post('/login', passport.authenticate('login', {
successRedirect: '/auth/success',
failureRedirect: '/auth/failure'
}));
//sign up
router.post('/signup', passport.authenticate('signup', {
successRedirect: '/auth/success',
failureRedirect: '/auth/failure'
}));
//log out
router.get('/signout', function(req, res) {
req.logout();
res.redirect('/');
});
return router;
}
here is my passport-init.js
var LocalStrategy = require('passport-local').Strategy;
var bCrypt = require('bcrypt-nodejs');
//temporary data store
var users = {};
module.exports = function(passport){
// Passport needs to be able to serialize and deserialize users to support persistent login sessions
passport.serializeUser(function(user, done) {
console.log('serializing user:',user.username);
return done(null, user.username);
});
passport.deserializeUser(function(username, done) {
return done('we have not implemented this', false);
});
passport.use('login', new LocalStrategy({
passReqToCallback : true
},
function(req, username, password, done) {
if(!users[username]){
console.log('User Not Found with username '+username);
return done(null, false);
}
if(isValidPassword(users[username], password)){
//sucessfully authenticated
return done(null, users[username]);
}
else{
console.log('Invalid password '+username);
return done(null, false)
}
}
));
passport.use('signup', new LocalStrategy({
passReqToCallback : true // allows us to pass back the entire request to the callback
},
function(req, username, password, done) {
// if (users[username]){
// console.log('User already exists with username: ' + username);
// return done(null, false);
// }
//store user in memory
users[username] = {
username: username,
password: createHash(password)
}
console.log(users[username].username + ' Registration successful');
return done(null, users[username]);
})
);
var isValidPassword = function(user, password){
return bCrypt.compareSync(password, user.password);
};
// Generates hash using bCrypt
var createHash = function(password){
return bCrypt.hashSync(password, bCrypt.genSaltSync(10), null);
};
};
When i try to hit the signup api from postman it always redirect to failure api. I also have tried with the debugger but i am not getting the controller over there.
just uncomment following line in app.js
//app.use(bodyParser.json());
//app.use(bodyParser.urlencoded({ extended: false }));
and update passport-init.js
passport.deserializeUser(function(username, done) {
return done('we have not implemented this', false);
});
to
passport.deserializeUser(function(username, done) {
return done(null, users[username]);
});

NodeJS server crash after save data to mongoDB

I wrote a script which save an object to a MongoDB database using mongoose. The object is correctly save to the database, but the server crashes right after, throwing me the following error message: catch(err) { process.nextTick(function() { throw err}); }
Here's a part of my code:
users.js
var User = require('../models/user');
router.post('/register', function(req, res, next) {
[...]
// checks for errors
var errors = req.validationErrors();
if (errors) {
res.render('register', {
errors: errors,
[...]
})
} else {
var newUser = new User({
[...]
});
// Create user
User.createUser(newUser, function(err, user) {
if (error) {
throw err;
};
console.log(user);
});
[...]
}
});
module.exports = router;
user.js
var mongoose = require('mongoose');
mongoose.connect('mongodb://localhost/nodeauth');
// User Schema
var UserSchema = mongoose.Schema({
[...]
});
var User = module.exports = mongoose.model('User', UserSchema);
module.exports.createUser = function(newUser, callback) {
newUser.save(callback);
}
apps.js
var express = require('express');
var path = require('path');
var favicon = require('serve-favicon');
var logger = require('morgan');
var cookieParser = require('cookie-parser');
var session = require('express-session');
var passport = require('passport');
var localStrategy = require('passport-local').Strategy;
var bodyParser = require('body-parser');
var multer = require('multer');
var flash = require('connect-flash');
var mongo = require('mongodb');
var mongoose = require('mongoose');
var db = mongoose.connection;
var expressValidator = require('express-validator');
var routes = require('./routes/index');
var users = require('./routes/users');
var app = express();
// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'jade');
// handle file uploads
app.use(multer({dest:'./uploads'}).single('singleInputFileName'));
// 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: false }));
// handle express session
app.use(session({
secret: 'secret',
saveUninitialized: true,
resave: true
}));
// passport
app.use(passport.initialize());
app.use(passport.session());
// validator
app.use(expressValidator({
errorFormatter: function(param, msg, value) {
var namespace = param.split('.')
, root = namespace.shift()
, formParam = root;
while(namespace.length) {
formParam += '[' + namespace.shift() + ']';
}
return {
param : formParam,
msg : msg,
value : value
};
}
}));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));
// connect flash
app.use(flash());
app.use(function (req, res, next) {
res.locals.messages = require('express-messages')(req, res);
next();
});
app.use('/', routes);
app.use('/users', users);
// 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;
You shouldn't throw error you should return it in handler to let clients know if there is a database error creating the user. Only throw when caller can catch error, async code cannot be caught easily. Promises enable throwing errors but not callbacks.

Categories