I'm using a passport-local strategy for authenticate users. I followed the guide given by Jared Hanson and installed connect-flash in order to give flash method to the req object. So one of my request handlers is the following:
app.post('/login',
passport.authenticate('local', {
successRedirect: '/'
, failureRedirect: '/login'
, successFlash: 'Bienvenido'
, failureFlash: 'Credenciales no válidas'
})
);
When the user login fails, it redirects the user to /login again but it doesnt flash anything :/
UPDATE:
I use mongodb for session storage and I see this:
> db.sessions.find()
{ "_id" : "qZ2eiTnx6r9LR25JOz/TGhiJ", "session" : "{\"cookie\":{\"originalMaxAge\":null,\"expires\":null,\"httpOnly\":true,\"path\":\"/\"},\"passport\":{\"user\":\"4ffb5b5db9cc16b615000001\"},\"flash\":{\"error\":[\"Credenciales no válidas\"],\"success\":[\"Bienvenido\"]}}" }
So the messages are inserted into the session object but they aren't pulled out. Should I do something special?
I assume you're pulling the messages out and rendering them in a view? Something like:
app.get('/login', function(req, res){
res.render('login', { message: req.flash('error') });
});
Related
I am building an application using node.js and express.js with passport authentication using MVC Architecture. I have strictly followed a tutorial on how to implement and integrate passport authentication using a local strategy. It seems like the strategy is working fine. In my controller which is handling the authentication (using passport.authenticate), successRedirect is always executed given that I submit matching details with an instance in the database. However, after redirecting to wherever successRedirect points to, I am getting a GET request Error 500. Afterwards, if I try to access other routes, I still get the same error, thus failing to display the desired view template. However, if I try to access the same routes without attempting to login, the GET request executes successfully with statusCode 200.
The exact error I get is :
GET /dashboard 500 4.313 ms - 941
users.js route
var usersController = require('../../controllers/usersController');
/* POST login */
router.post('/login', usersController.loginAccount);
usersController.js
module.exports.loginAccount = function (req, res, next) {
passport.authenticate('local', {
successRedirect: 'dashboard',
failureRedirect: '/users/login',
failureFlash: true
}) (req, res, next);
}
index.js route
router.get('/dashboard', ensureAuthenticated, indexController.dashboardPage);
function ensureAuthenticated(req, res, next) {
if (req.isAuthenticated())
return next();
else{
req.flash('error_msg', 'Please log in to view this resource');
res.redirect('/users/login');
}
}
Command line after attempting login:
Executing (default): SELECT id, firstname, lastname, email, username, password, address, createdAt, updatedAt FROM clients AS client WHERE client.username = 'nikolaisennn' LIMIT 1;
Serializing user
POST /users/login 302 144.266 ms - 74
Deserializing user
User ID: 65
GET /dashboard 500 4.313 ms - 941
I have been stuck on this issue for a while, tried to find solutions online but I haven't really managed to find what I need. I am sure that there is something small that I am missing, yet I have no clue what it is.
I am developing a web app where after login according to type of user the page should redirect. type of user is defined by user at the time of sign-up. passport local authentication is working fine but what I have to do for redirecting the page according to usertype.. please guide
If the passport is working you could probably get that information off of the request and then use res.redirect('/whereYouWant'). Post some code? check out this answer for info on looking at the cookie: How to access Cookie set with Passport.js
Why not redirect to a page which takes of any redirections for you? Example:
router.get('/login', function(req, res) {
res.render('login', { user : req.user, status: req.param('status') });
});
router.post('/login', passport.authenticate('local', {
successRedirect: '/redirect',
failureRedirect: '/login?status=fail',
}));
router.get('/redirect', function(req, res) {
if (req.isAuthenticated()) {
if (req.user.usertype === "admin") {
res.redirect('/adminpage');
}
if (req.user.usertype === "marketing") {
res.redirect('/marketingpage');
}
......
}
});
With Passport and Express, I succeed handling user session. Because I have some pages, that do not need be logged to be viewed, a user can login in many page.
How should I handle passport.authenticate to redirect on the current page, augmented with user data.
app.post('/login',
passport.authenticate('local', { successRedirect: '/',
failureRedirect: '/login',
failureFlash: true })
);
Maybe a custom callback with a res.send(req.user). As I'm completely not familiar, i just advises on this.
The user info will be put on the req.user "by passport"
app.post('/login',
passport.authenticate('local-login', {
successRedirect : 'back', // redirect back to the previous page
failureRedirect : 'back', // redirect back to the previous page
failureFlash : true
})
);
The keyword backredirect to previous page.
I am setting up what I thought would be the simplest auth possibly - a site loads on a log in screen, user enters credentials in a form, on submission I am using Passport.JS and Sequelize to check the credentials. Most all of this is copied from various tutorials, or the Passport website itself.
No matter what I do, change or attempt though, the site just hangs as soon as I click the form submit button. In the dev tools network tab I just shows the post request to /login as pending.
To eliminate all possible added problems, I stripped out Sequelize, and used hard coded users, ala the local use example on the passport github page. Still, no change, to Sequelize was not the problem.
I'm sure it's something dumb. I've tried the obvious solutions, like making sure my form was sending 'username' and 'password'.
My form looks like this:
form(method="post", action="/login")
fieldset
legend Please Log In
label(for="username") Username:
input#username(type='text', name="username", autocomplete="off")
label(for="password") Password:
input#password(type='password', name="password")
button#login(type="submit") Log In
In node my app.js uses a router, which includes this:
var login = require('../app/controllers/login');
app.get('/', login.index);
app.post('/login', login.auth);
The page load ok on the get request. On post it directs to this:
exports.auth = function (req, res, next) {
console.log(req.body);
passport.authenticate('local', {
successRedirect: '/home',
failureRedirect: '/',
failureFlash: true
});
};
The console.log(req.body) comes up fine, showing the form values, so we are ok to that point. But nothing after. This is the last part:
passport.use(new LocalStrategy(
function(username, password, done) {
console.log('local strat invoked');
findByUsername(username, function(err, user) {
if (err) { return done(err); }
if (!user) { return done(null, false, { message: 'Unknown user ' + username }); }
if (user.password != password) { return done(null, false, { message: 'Invalid password' }); }
return done(null, user);
});
}
));
I swapped out the code that used Sequelize to check the DB for the user with this findByUsername function (copied and pasted straight from the above mentioned post on the passport github page), but as the console.log('local strat invoked') is never coming up, I'm guessing nothing after that point even matters.
Also includes are the passport.serializeUser and passport.deserializeUser, but I cant imagine those are the problem at the stage where I am stuck.
Any idea what step I am missing to get this working?
Passport is middleware, if you embed it in a route handler function, you need to invoke it:
exports.auth = function (req, res, next) {
console.log(req.body);
passport.authenticate('local', {
successRedirect: '/home',
failureRedirect: '/',
failureFlash: true
})(req, res, next); // <-- NEED TO INVOKE WITH req, res, next
};
or, more simply use it as middleware (which is the recommended approach:
exports.auth = passport.authenticate('local', {
successRedirect: '/home',
failureRedirect: '/',
failureFlash: true
});
I am using Passport-Local (https://github.com/jaredhanson/passport-local) to authenticate with node.js. So far this example works like a charm, since the users are logging in thorugh a post-webform:
app.post('/login',
passport.authenticate('local', { failureRedirect: '/login', failureFlash: true }),
function(req, res) {
res.redirect('/');
});
Now, however, I want to code up a JSON-based API to authenticate users by calling a particular URL. Modifying the code block to app.get(… doesn't work though.
Any advice?
I ran into this same problem, and solved it by adding this to my route handler for login:
req.body = req.query;
Maybe not the perfect solution, but it's certainly better than hacking passport. ;)
Also note that there's a pending request in passport-local to fix this problem: https://github.com/jaredhanson/passport-local/pull/12
Maybe https://github.com/yarax/passport-url strategy will be useful for you
It allows to authenticate users with a token giving by GET request
var url = new UrlStrategy({
failRedirect : "/login",
varName : "secret"
}, function (secret, done) { // put your check logic here
if (secret == 'foo') done(null, {id:'bar'});
else done("wrong");
});
passport.use(url);