In my nodejs app it shows an error like:
req.flash is not a function
I have installed connection-flash npm and session and express-session but instead of that it is throwing an error like:
TypeError: req.flash is not a function
in line no. 42 in my register.js. I googled it several times but did not find any proper solution. How can I solve this? Thanks in advance.
This is my register.js:
var express = require('express');
var router = express.Router();
var User = require('../models/user');
var flash = require('connect-flash');
router.get('/', (req, res, next) => {
res.render('register');
})
router.post('/', (req, res, next) => {
var name = req.body.name;
var username = req.body.username;
var email = req.body.email;
var password = req.body.password;
var cpassword = req.body.cpassword;
req.checkBody('name', 'Name is required').notEmpty();
req.checkBody('username', 'User Name 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();
req.checkBody('cpassword', 'Password do not match').equals(req.body.password);
var errors = req.validationErrors();
if(errors){
res.render('register', {
errors:errors
});
}else{
var newUser = new User({
name: name,
username: username,
email: email,
password: password
});
User.createUser(newUser, function(err, user){
if(err) throw err;
console.log(user)
});
req.flash('success_msg', 'Successfully Registered');
res.redirect('/login');
}
})
module.exports = router;
And this is my app.js:
var createError = require('http-errors');
var express = require('express');
var path = require('path');
var bodyParser = require('body-parser');
var cookieParser = require('cookie-parser');
var logger = require('morgan');
var expressValidator = require('express-validator');
var passport = require("passport");
var LocalStrategy = require('passport-local').Strategy;
var session = require('session');
var flash = require('connect-flash');
var mongoose = require('mongoose');
var indexRouter = require('./routes/index');
var usersRouter = require('./routes/users');
var loginRouter = require('./routes/login');
var registerRouter = require('./routes/register');
var app = express();
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'twig');
app.use(expressValidator());
app.use(logger('dev'));
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));
app.use('/', indexRouter);
app.use('/users', usersRouter);
app.use('/login', loginRouter);
app.use('/register', registerRouter);
app.use(flash());
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(passport.initialize());
app.use(passport.session());
app.use(function(req, res, next) {
next(createError(404));
});
app.use(function(err, req, res, next) {
res.locals.message = err.message;
res.locals.error = req.app.get('env') === 'development' ? err : {};
res.status(err.status || 500);
res.render('error');
});
module.exports = app;
Do you try move app.use(flash()) before app.use('/register... ?
app.use(flash());
app.use('/', indexRouter);
app.use('/users', usersRouter);
app.use('/login', loginRouter);
app.use('/register', registerRouter);
and base of flash-connection documnet
Flash messages are stored in the session. First, setup sessions as usual by enabling cookieParser and session middleware. Then, use flash middleware provided by connect-flash.
Follow the document instruction to use flash properly
Use express-flash instead:
npm install express-flash --save
In app.js file add
flash = require('express-flash')
app.use(
session({
resave: true,
saveUninitialized: true,
secret:"yash is a super star",
cookie: { secure: false, maxAge: 14400000 },
})
);
app.use(flash());
use req.flash function wherever you want to send flash messages
res.flash("info","this message will be displayed");
res.redirect('');
In index.hbs file include
{{#if messages.info}}
{{messages.info}}
{{if}}
Define session first.
app.use(
session({
secret: 'secret',
resave: true,
saveUninitialized: true
})
);
Then Define flash
app.use(flash());
Then define your router
app.use('/', indexRouter);
app.use('/users', usersRouter);
The way how you arranged your middlewares are wrong.
If you want to use the flash middileware in your route files, then the flash middileware should be above your router middileware.
Like this:
app.use(flash());
app.use('/', indexRouter);
app.use('/users', usersRouter);
app.use('/login', loginRouter);
app.use('/register', registerRouter);
Related
I am using the following code to implmenet twitter Oauth in node.js. The token and tokenSecret are not showing up in the console.
Everything else is working correctly, like the login, authentication, and callback functions.
All I see in the console are the access logs like the following:
GET / 304 197.320 ms - -
GET /stylesheets/style.css 304 2.092 ms - -
GET /auth/twitter 302 404.252 ms - 0
All I want to do is show the access token and access secret of the authenticated user.
var createError = require('http-errors');
var express = require('express');
var session = require('express-session');
var path = require('path');
var cookieParser = require('cookie-parser');
var logger = require('morgan');
var passport = require('passport');
var TwitterStrategy = require('passport-twitter').Strategy;
var config = require('./config');
var indexRouter = require('./routes/index');
var usersRouter = require('./routes/users');
var app = express();
// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'jade');
app.use(logger('dev'));
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));
app.use(session({
secret: 'secret-key',
resave: true,
saveUninitialized: true
}));
app.use(passport.initialize());
app.use(passport.session());
// passport-twitter settings
passport.use(new TwitterStrategy({
consumerKey: config.consumerKey,
consumerSecret: config.consumerSecret,
callbackURL: config.callbackURL
},
// After authentication
function(token, tokenSecret, profile, done) {
console.log("token: " + token);
console.log("tokenSecret: " + tokenSecret);
return done(null, profile);
}
));
// Save to session
passport.serializeUser(function(user, done) {
done(null, user);
});
passport.deserializeUser(function(user, done) {
done(null, user);
});
app.use('/', indexRouter);
app.use('/success', usersRouter);
app.get('/auth/twitter', passport.authenticate('twitter'));
app.get('/auth/twitter/callback',
passport.authenticate('twitter', { failureRedirect: '/?auth_failed' }),
function (req, res) {
res.redirect('/success');
});
// 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;
I set the callback url in the twitter app page to "http://localhost:3000/auth/twitter/callback" and it worked.
I am following this tutorial on creating an authentication system with passport in Nodejs
Currently I am trying to make the signup form work, but it gives this error:
Error: Unknown authentication strategy "local-signup"
at attempt (/home/jarno/0__projects/nodejs/EasyOrders_2.3.0/node_modules/passport/lib/middleware/authenticate.js:173:37)
at authenticate (/home/jarno/0__projects/nodejs/EasyOrders_2.3.0/node_modules/passport/lib/middleware/authenticate.js:349:7)
at Layer.handle [as handle_request] (/home/jarno/0__projects/nodejs/EasyOrders_2.3.0/node_modules/express/lib/router/layer.js:95:5)
at next (/home/jarno/0__projects/nodejs/EasyOrders_2.3.0/node_modules...
I am pretty sure that the config/passport.js file isn't seen by the routes/users.js file, but as I am a beginner I can't seem to find a solution to my problem.
/routes/users.js
var express = require('express');
var router = express.Router();
var passport = require('passport');
require('../config/passport');
/* GET users listing. */
router.get('/login', function(req, res){
res.render('login', {
title: 'Login'
});
});
router.get('/signup', function(req, res){
res.render('signup', {
title: 'signup'
});
});
router.get('/logout', function(req, res){
res.logout();
res.redirect('/users/login')
});
/* POST users listing */
router.post('/signup', passport.authenticate('local-signup', {
successRedirect : '/profile', // redirect to the secure profile section
failureRedirect : '/signup', // redirect back to the signup page if there is an error
failureFlash : true // allow flash messages
}));
/* functions */
function isLoggedIn(req, res, next) {
if (req.isAuthenticated())
return next();
res.redirect('/users/login');
}
module.exports = router;
/config/passport.js
// config/passport.js
var passport = require('passport');
// load all the things we need
var LocalStrategy = require('passport-local').Strategy;
// load up the user model
var User = require('../models/user');
// expose this function to our app using module.exports
module.exports = function(passport) {
// =========================================================================
// passport session setup ==================================================
// =========================================================================
// required for persistent login sessions
// passport needs ability to serialize and unserialize users out of session
// used to serialize the user for the session
passport.serializeUser(function(user, done) {
done(null, user.id);
});
// used to deserialize the user
passport.deserializeUser(function(id, done) {
User.findById(id, function(err, user) {
done(err, user);
});
});
// =========================================================================
// LOCAL SIGNUP ============================================================
// =========================================================================
// we are using named strategies since we have one for login and one for signup
// by default, if there was no name, it would just be called 'local'
passport.use('local-signup', new LocalStrategy({
// by default, local strategy uses username and password, we will override with email
usernameField : 'email',
passwordField : 'password',
passReqToCallback : true // allows us to pass back the entire request to the callback
},
function(req, email, password, done) {
// asynchronous
// User.findOne wont fire unless data is sent back
process.nextTick(function() {
// find a user whose email is the same as the forms email
// we are checking to see if the user trying to login already exists
User.findOne({ 'local.email' : email }, function(err, user) {
// if there are any errors, return the error
if (err)
return done(err);
// check to see if theres already a user with that email
if (user) {
return done(null, false, req.flash('signupMessage', 'That email is already taken.'));
} else {
// if there is no user with that email
// create the user
var newUser = new User();
// set the user's local credentials
newUser.local.email = email;
newUser.local.password = newUser.generateHash(password);
// save the user
newUser.save(function(err) {
if (err)
throw err;
return done(null, newUser);
});
}
});
});
}));
};
/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 mongoose = require('mongoose');
var passport = require('passport');
var flash = require('connect-flash');
var morgan = require('morgan');
var session = require('express-session');
var configDB = require('./config/database.js');
mongoose.connect(configDB.url);
require('./config/passport');
// init app
var app = express();
var index = require('./routes/index');
var users = require('./routes/users');
// 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(morgan('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(require('stylus').middleware(path.join(__dirname, 'public')));
app.use(express.static(path.join(__dirname, 'public')));
app.use(session({ secret: 'godaddy420' })); // session secret
app.use(passport.initialize());
app.use(passport.session()); // persistent login sessions
app.use(flash()); // use connect-flash for flash messages stored in session
app.use(function (req, res, next) {
res.locals.path = req.path;
next();
});
app.use('/', index);
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;
config/password.js exports a function but you never call this function. In app.js, you should have something like that :
require('./config/passport')(passport);
)You have to set the routes with passport after the app.use() methods and send passport as argument. so:
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 mongoose = require('mongoose');
var passport = require('passport');
var flash = require('connect-flash');
var morgan = require('morgan');
var session = require('express-session');
var configDB = require('./config/database.js');
mongoose.connect(configDB.url);
require('./config/passport');
// init app
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(morgan('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(require('stylus').middleware(path.join(__dirname, 'public')));
app.use(express.static(path.join(__dirname, 'public')));
app.use(session({ secret: 'godaddy420' })); // session secret
app.use(passport.initialize());
app.use(passport.session()); // persistent login sessions
app.use(flash()); // use connect-flash for flash messages stored in session
app.use(function (req, res, next) {
res.locals.path = req.path;
next();
});
// require('./app/routes.js')(app, passport); // load our routes and pass in our app and fully configured passport
var index = require('./routes/index')(app, passport);
var users = require('./routes/users')(app, passport);
app.use('/', index);
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;
Inside 'index' and 'users' use the passport that you are sending as argument.
Below is the Code that i'm working on but i'm getting errors while executing.
Please help me in creating routes for both login and register forms which are on the same page.
When I'm submitting the registration form with this code, I'm getting an error which says "Bad request"
var express = require ('express');
var app = express();
var path= require('path');
var bodyParser = require('body-parser');
var mongoose = require("mongoose");
var nodemailer = require('nodemailer');
var transporter = nodemailer.createTransport();
var smtpTransport = require('nodemailer-smtp-transport');
var passport = require('passport');
var LocalStrategy = require('passport-local');
var passportLocalMongoose = require('passport-local-mongoose');
var User = require('./models/user');
app.set('port', process.env.PORT || 3000);
app.use(bodyParser.json()); // support json encoded bodies
app.use(bodyParser.urlencoded({ extended: true })); // support encoded bodies
app.use(express.static(path.join(__dirname, 'public')));
app.set("view engine", "ejs");
app.use(require('express-session')({
secret: 'Working on enroll Medicare',
resave: false,
saveUninitialized: false
}));
app.use(passport.initialize());
app.use(passport.session());
passport.use(new LocalStrategy(User.authenticate()));
passport.serializeUser(User.serializeUser());
passport.deserializeUser(User.deserializeUser());
mongoose.connect("mongodb://localhost/registration");
app.post('/login-register.html', function(req,res)
{
var username = req.body.usernameregister;
var email = req.body.emailregister;
var password1 = req.body.password1register;
var password2 = req.body.password2register;
password1, password2: password2}
User.register(new User({username: username, email: email}), password1, function(err, user){
if(err){
console.log(err);
return res.render('error');
}
passport.authenticate('local')(req, res, function(){
res.redirect("/secret");
});
});
});
login page
app.post("/login-register.html", passport.authenticate('local', {
succesRedirect: "/secret",
failureRedirect: "/error"
}), function(req, res){ });
I think you may have multiple problems here. Here are a few things to check:
You have passport.use(new LocalStrategy(User.authenticate()));. I don't know what User.authenticate() returns, but it should return a function with the arguments function(username, password, done) {...}
It looks like you're using email as the username. You need to add usernameField to the strategy options: new LocalStrategy({usernameField: 'email'}, function(email, password, done){...})
I've also found it really helpful to use a custom callback in the passport.authenticate function to see if the returned error provides any more information about the problem: passport.authenticate('local', function(err, user, info) {console.log(err, user, info)})
I am using passport.js for a basic log in/log out system. For some reason, the router.get('/signout', function(req, res)) is not being called when I run http://localhost:3000/auth/signout on Advanced rest client. Instead I am getting a Internal Server Error: 500. Login works just fine, but signout does not. Here is my app.js and authenticate.js:
App.js
var express = require('express');
var path = require('path');
var favicon = require('serve-favicon');
var logger = require('morgan');
var passport = require('passport');
var session = require('express-session');
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');
//Initialize models
require('./models/models.js');
var api = require('./routes/api');
var authenticate = require('./routes/authenticate')(passport);
var mongoose = require('mongoose');
//connect to mongodb
mongoose.connect("mongodb://localhost:27017/chirp-test");
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: 'super duper secret'
}));
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()); //This creates a unique has for our session
//Initialize Passport
var initPassport = require('./passport-init');
initPassport(passport);
app.use('/auth', authenticate);
app.use('/api', api);
// 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;
Authenticate.js
var express = require('express');
var router = express.Router();
module.exports = function(passport){
//sends successful login state back to angular
router.post('/success', function(req, res){
console.log('successful');
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 password"});
});
//log in
router.post('/login', passport.authenticate('login', { failureRedirect: '/auth/failure' }),
function(req, res) {
//res.redirect('/auth/success');
res.send({state: 'success', user: req.user ? req.user : null});
});
//sign up
router.post('/signup', passport.authenticate('signup', {
successRedirect: '/auth/success',
failureRedirect: '/auth/failure'
}));
//log out
router.get('/signout', function(req, res) {
console.log('Signing out...');
req.logout();
res.redirect('/');
});
return router;
}
You have registered nothing under "/". So when "auth/logout" call redirect to redirect("/"), I guess client is redirected but goes into your "error handler" which sends a 500 error...
I try to send a form with data in my nodejs app but I get "undefined" I am not sure does it matter but in console first I see "undefined", then POST. I have tried some "fixes" from the Internet like adding "type:'application/*+json', inflate: false" to app.use(bodyParser.json...) but nothing worked for me...
Undefined
POST /users/register 200 32.777 ms - 2346
this is my routes/users.js file:
var express = require('express');
var router = express.Router();
router.get('/register', function(req, res, next) {
res.render('register', {
'title': 'Register'
});
});
router.post('/register', function(req, res, next) {
console.log(req.body.name);
});
module.exports = router;
heres my jade file
form(method='post', action='/users/register', role='form')
.form-group
label Name
input.form-control(type='text', name='name', placeholder='Enter Name')
input.btn.btn-default(name='submit', type='submit', value='Register')
and 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 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();
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'jade');
app.use(logger('dev'));
app.use(bodyParser.json({ type: 'application/*+json' }));
app.use(session({
secret: 'secret',
saveUninitialized: true,
resave: true
}));
app.use(passport.initialize());
app.use(passport.session());
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);
app.use(function(req, res, next) {
var err = new Error('Not Found');
err.status = 404;
next(err);
});
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
});
});
}
app.use(function(err, req, res, next) {
res.status(err.status || 500);
res.render('error', {
message: err.message,
error: {}
});
});
module.exports = app;
Routing works fine what show setting up a title to "Register", but I have problems with sending post :/
You're configuring body-parser to only accept JSON request bodies, but your form is submitted in URL-encoded format (application/x-www-form-urlencoded).
For that, you need to add the correct parser:
app.use(bodyParser.urlencoded({ extended : true }));
More information, also on the meaning of extended : true, here.