I want to use express-validator in my app.
Here is my app.js code:
app.set('port', process.env.PORT || 3000);
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'jade');
app.use(express.logger('dev'));
app.use(express.methodOverride());
app.use(app.router);
app.use(express.bodyParser());
app.use(express.urlencoded());
app.use(express.json());
app.use(expressValidator());
Below is my route:
module.exports = function(app) {
app.post('/login', userController.login);
}
And here is my code for login:
exports.login = function(req, res, next) {
req.assert('email', 'Email not valid').isEmail();
var errors = req.validationErrors();
if (errors) {
return res.redirect('/login');
}
passport.authenticate('local', function(err, user, info) {
// do stuff
})(req, res, next);
};
When I try to post something to /login I got the follwoing error message :
TypeError: Object # <IncomingMessage> has no method 'assert'
I saw that this might be related to an issue with app.use but right now i'm stuck...
EDIT 1 :
I change my app.use to those ones, but it doesn't solve my issue:
app.use(express.logger('dev'));
app.use(express.methodOverride());
app.use(express.bodyParser());
app.use(express.urlencoded());
app.use(express.json());
app.use(expressValidator());
app.use(app.router);
You should use app.router only after any middleware that you're going to use in your routes:
app.use(express.methodOverride());
app.use(express.bodyParser());
app.use(express.urlencoded());
app.use(express.json());
app.use(expressValidator());
app.use(app.router);
The reason is that the order in which you declare middleware with Express is very important: if you add app.router before expressValidator, it means, that the router middleware will get to handle requests before the validator middleware is even called and got a chance to add its magic to req.
I had the same issue! your app.js and route.js code are just fine, but in your code for login, you have to change from:
req.assert('email', 'Email not valid').notEmpty();
and replace it for:
req.check('email', 'Email not valid').notEmpty();
If you see the code https://github.com/ctavan/express-validator/blob/master/lib/express_validator.js on line 198, assert is only an alias for check. And seems to have an issue with that name "assert", maybe confuses nodejs because there is a module called "assert", is only a guess.
Anyway, seems to work just fine with it.
Hope it helps!
Kindly check by replacing assert with checkBody.
req.checkBody('email', 'Email not valid').notEmpty().
Do it like this.
Related
I'm tinkering with server side requirejs and I have a problem with routes. My routes/index.js file has:
/*
* GET home page.
*/
exports.index = function(req, res){
res.render('index', { title: 'Express' });
};
});
and in my server.js I have:
define(['express', 'module', 'path', './routes'],
function (express, module, path, routes) {
var app = express();
app.configure(function() {
// all environments
var filename = module.uri;
app.set('port', process.env.PORT || 3000);
app.use(express.static(path.dirname(filename) + '/views'));
app.set('view engine', 'jade');
app.use(express.favicon());
app.use(express.logger('dev'));
app.use(express.bodyParser());
app.use(express.methodOverride());
app.use(express.cookieParser('your secret here'));
app.use(express.session());
app.use(app.router);
app.use(express.static(path.dirname(filename) + '/public'));
});
// development only
if ('development' == app.get('env')) {
app.use(express.errorHandler());
}
app.get('/', routes.index);
return app;
});
When I run this I get the following error:
500 Error: Failed to lookup view "index"
at Function.app.render (/Users/johnwesonga/backbonejs/src/helloworld/node_modules/express/lib/application.js:489:17)
at ServerResponse.res.render (/Users/johnwesonga/backbonejs/src/helloworld/node_modules/express/lib/response.js:755:7)
at exports.index (/Users/johnwesonga/backbonejs/src/helloworld/routes/index.js:7:9)
at callbacks (/Users/johnwesonga/backbonejs/src/helloworld/node_modules/express/lib/router/index.js:161:37)
at param (/Users/johnwesonga/backbonejs/src/helloworld/node_modules/express/lib/router/index.js:135:11)
at pass (/Users/johnwesonga/backbonejs/src/helloworld/node_modules/express/lib/router/index.js:142:5)
at Router._dispatch (/Users/johnwesonga/backbonejs/src/helloworld/node_modules/express/lib/router/index.js:170:5)
at Object.router (/Users/johnwesonga/backbonejs/src/helloworld/node_modules/express/lib/router/index.js:33:10)
at next (/Users/johnwesonga/backbonejs/src/helloworld/node_modules/express/node_modules/connect/lib/proto.js:190:15)
at next (/Users/johnwesonga/backbonejs/src/helloworld/node_modules/express/node_modules/connect/lib/middleware/session.js:313:9)
Any clue where i'm going wrong?
It could be simply that something has been cached or needs to be restarted.
Unfortunately I don't have a definitive answer, but I was having a similar problem: everything seemed to be set up correctly however I was getting an error saying that it couldn't find the view. I gave up, switched off the computer then came back to it the next morning.....and it worked.
I hope this provides a clue for anyone looking at this post, (as I did), in the future
I'm trying to set some response-specific variables, and I'm getting undefined for res.locals when I log it from within my middleware, but it returns the function just fine if I log it from within a route function.
// all environments
app.set('port', process.env.PORT || 3000);
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'jade');
app.use(express.favicon());
app.use(express.logger('dev'));
app.use(express.json());
app.use(express.urlencoded());
app.use(express.methodOverride());
app.use(function (res, req, next) {
console.log("res.locals from app.use middleware: ", res.locals);
// res.locals.boom = 'nice';
// res.locals.zoom = 'yeah!';
next();
});
app.use(app.router);
app.use(require('stylus').middleware(path.join(__dirname, 'public')));
app.use(express.static(path.join(__dirname, 'public')));
Any ideas?
You have your request & response objects backwards. Obviously if you know the difference in your code, naming doesn't matter, but best to keep things named correctly.
app.use( function (request, response, next) {
// stuff
});
I can't recall off the top of my head, but I believe you want:
request.app.locals;
using my example above. Again, not 100% sure. You can always console out the request object to check.
The app.locals object is a JavaScript Function, which when invoked with an object will merge properties into itself, providing a simple way to expose existing objects as local variables.
app.locals({
title: 'My App',
phone: '1-250-858-9990',
email: 'me#myapp.com'
});
app.locals.title
// => 'My App'
app.locals.email
// => 'me#myapp.com'
I'm having some problems trying to implement some middleware in my app.
Specicially, the app.use() does not seem to catch and I don't understand why.
Below is roughly what I have.
routes/index.js
var Sessions = require('../events');
module.exports = exports = function(app) {
app.use(Sessions.isLoggedIn);
//app.use() does not catch but this does
//app.all('*', Sessions.isLoggedIn);
// Home Page
app.get('/', displayHome);
app.get('/:library/:books', displayLibrary);
}
events.js
module.exports = exports = {
isLoggedIn: function(req, res, next) {
console.log('isLoggedIn');
return next();
}
Any suggestions as to why app.use() is not catching?
UPDATE:
Here is the configuration in ape.js
app.configure(function() {
app.set('port', process.env.VCAP_APP_PORT || 3000);
app.set('views', __dirname + '/views');
app.set('view engine', 'jade');
app.use(express.logger('dev'));
app.use(express.compress()); // compress responses
app.use(express.bodyParser());
app.use(express.methodOverride());
app.use(expressValidator);
app.use(express.cookieParser('locket'));
app.use(express.cookieSession({
key: 'locket',
secret: 'mySecret',
cookie: {httpOnly: true, expires: 0, path: '/'}
}));
// cache every file going out
app.use(function(req, res, next) {
if (!res.getHeader('Cache-Control')) {
res.setHeader('Cache-Control', 'public, max-age=' + (86400 / 1000));
}
next();
});
app.use(app.router);
app.use(express.static(path.join(__dirname, 'public')));
});
app.configure('development', function(){
app.use(express.errorHandler({showStack: true, dumpExceptions: true}));
});
routes(app);
The router is responding to the request before your middleware function has a chance to run.
app.js sets up several other middleware functions, then uses app.router. You then call your routes/index.js file, which uses a new middleware function which gets added after app.router.
use your isLoggedIn function before the router, or use it specifically with the routes that need to check login state:
app.get('/', Sessions.isLoggedIn, function(req, res) { ... });
I want to display a flash message after a user fails to sign in but I just can't get the variables to show up in my Jade views.
I have some pieces, I know I have to use this in my app.configure():
app.use (req, res, next) ->
res.locals.session = req.session
And I'll set what the flash message is after the user POSTS the wrong password:
exports.postSession = (req, res) ->
users = require '../DB/users'
users.authenticate(req.body.login, req.body.password, (user) ->
if(user)
req.session.user = user
res.redirect(req.body.redirect || '/')
else
req.session.flash = 'Authentication Failure!'
res.render('sessions/new', {title:'New', redirect: req.body.redirect })
)
I don't know how to access res.locals.session in my Jade file. I doubt I am setting everything up right. This question is a lot like this one: Migrating Express.js 2 to 3, specifically app.dynamicHelpers() to app.locals.use? but I still can't get it to work. It would be much appreciated if someone could show me just a simple example of setting values in res.local and accessing them in a view.
p.s. I do know about connect-flash but I need to understand how to make things available in views.
This is my app:
app.configure(() ->
app.set('views', __dirname + '/views')
app.set('view engine', 'jade')
app.use(express.bodyParser())
app.engine('.jade', require('jade').__express)
app.use(express.methodOverride())
app.use(express.cookieParser())
app.use(express.session({ store: new express.session.MemoryStore({reapInterval: 50000 * 10}), secret: 'chubby bunny' }))
app.use(express.static(__dirname + '/public'))
app.use((req, res, next) ->
res.locals.session = req.session
next()
)
app.use(app.router)
)
Just to give a short summary for everyone who has the same problem and got the impression that is was solved changing res.redirect.
It is very important to put your app.use middleware before app.router. See the comments by TJ Holowaychuck, the author of express
https://groups.google.com/d/msg/express-js/72WPl2UKA2Q/dEndrRj6uhgJ
Here is an example using a fresh installation of express v3.0.0rc4
app.js:
app.use(function(req, res, next){
res.locals.variable = "some content";
next();
})
app.configure(function(){
app.set('port', process.env.PORT || 3000);
app.set('views', __dirname + '/views');
app.set('view engine', 'jade');
app.use(express.favicon());
app.use(express.logger('dev'));
app.use(express.bodyParser());
app.use(express.methodOverride());
app.use(app.router);
app.use(express.static(path.join(__dirname, 'public')));
});
index.jade:
extends layout
block content
h1= title
p Welcome to #{title}
p= variable
If you are using express.session() you must call your function AFTER express.session() but BEFORE app.router, inside of app.configure().
app.js
app = express();
app.configure(function(){
app.set('port', process.env.PORT || 3000);
app.set('views', __dirname + '/views');
app.set('view engine', 'jade');
app.use(express.logger('dev'));
app.use(express.bodyParser());
app.use(express.methodOverride());
app.use(express.session());
// Give Views/Layouts direct access to session data.
app.use(function(req, res, next){
res.locals.session = req.session;
next();
});
app.use(app.router);
app.use(express.static(path.join(__dirname, 'public')));
});
index.jade
extends layout
block content
h1= title
p My req.session.var_name is set to #{session.var_name}
I'm getting the following error while using Node.js and Express. Here are my versions :
Node : v0.8.8
Express: 3.0.0rc3
The following error is obtained while trying to access the page :
TypeError: Object #<IncomingMessage> has no method 'flash'
at routes (/Users/nblavoie/Desktop/HotPie/HotPie/apps/authentication/routes.js:23:8)
I've tried to remove the app.use(app.router); from the app.js with no success. Here is the code that causes the error. See req.flash line.
app.post('/sessions', function(req, res)
{
if(req.body.user == 'piechief'
&& req.body.password == '12345')
{
req.session.currentUser = req.body.user;
req.flash('info', "You're logged in as #{req.session.currentUser}");
res.redirect("/login");
return;
}
else
{
req.flash('error', "Those credentials were incorrect. Try again.");
res.redirect("/login");
return;
}
});
Here is the interesting part of my app.js :
var app = express();
app.configure(function(){
app.set('port', process.env.PORT || 3000);
app.set('views', __dirname + '/views');
app.set('view engine', 'jade');
app.use(express.favicon());
app.use(express.logger('dev'));
app.use(express.bodyParser());
app.use(express.methodOverride());
app.use(express.cookieParser());
app.use(express.session({
secret: "DBBD6BE563419EDB0E5CBD228E603D4AD232CE05434B4FA95C6908B64EA515C3",
store: new RedisStore({
host: "127.0.0.1",
port: "6379",
db: "mydb"
})
}));
app.use(app.router);
app.use(express.static(path.join(__dirname, '/public')));
});
Any idea please? I've took a loof at the Express'flash documentation and I can't see what I'm doing wrong.
req.flash has been removed as of 3.0:
req.flash() (just use sessions: req.session.messages = ['foo'] or similar)
connect-flash can be used as middleware to provide req.flash()
This solved it for me
https://github.com/jaredhanson/passport/issues/61
Now my passport app.configure looks like this:
app.configure(function (){
app.use(express.cookieParser('keyboard cat'));
app.use(express.session({ cookie: { maxAge: 60000 }}));
app.use(passport.initialize());
app.use(passport.session());
app.use(flash());
})