5

I'm using express 4, passport and express-flash. When I use the canned passport middleware function and set failureFlash: true, all works fine. But when I use a custom callback in my register function in the same routes file it doesn't work. The messages.info object is null.

This works fine:

    router.post('/login', passport.authenticate('local-login', {
        successRedirect: '/dashboard',
        failureRedirect: '/login',
        failureFlash: true
    }),
    function(req, res){
    }
);

This results in my messages.info object being null:

    router.post('/register', function(req, res, next){
    passport.authenticate('local-signup', function(err, user, info){
        if(err){
            req.flash('info', err);
            res.render('register');
        }else{
            res.render('profile');
        }
    })(req, res, next);
});

I'm using jade as my preprocessor:

    if (messages.info)
    .message.info
        span= messages.info

No worky!

shredmill
  • 283
  • 3
  • 10
  • Did you use `app.use(flash());` ? – Jay Jan 20 '16 at 05:22
  • Try to insert flash as authenticate option, i.e. passport.authenticate('local-signup', { failureFlash: true }, function(err, user, info){...}) – vzayko Jan 20 '16 at 07:16
  • I did use app.use(flash()); in my app.js file. When I put {failureFlash: true} in my local-signup function it throws a 500. I'm not sure why it's different in the inline middleware call vs the custom callback option... F@$ck! – shredmill Jan 21 '16 at 05:22

3 Answers3

4

This works (It prints out "no such user" when I put in wrong user. It also prints out "invalid password" with wrong combo.):

passport.use("login", new LocalStrategy(function(username, password, done){
  User.findOne({username : username}, function(err, user){
    if(err){return done(err)}
    if(!user){
        return done(null, false, {messages : "no such user" })
    }
    if(user.password != password){
        return done(null, false, {messages : "invalid password"})
    }else{
        return done(null , user);
    }
  })
}))



app.post("/login", function(req, res, next){
    passport.authenticate("login", function(err, user, info){
        if(err){ return next(err);}
        if(!user){return res.render("login", {messages : info.messages})}
        req.logIn(user, function(err){
            if(err){ return next(err); }
            return res.redirect("/authed");
        })
    })(req, res, next)
})
app.get("/login", function(req, res){
    console.log(req.session)
    res.render("login" , {messages : req.flash("error")} );
})

.ejs

<body>
    Log In
    <p><%=  messages %></p>
    <form action="/login" method = "post">
       username : <input type="text" name = "username"> <br>
       password : <input type="text" name = "password">
       <input type="submit" value = "Submit">
    </form>
</body>
jack blank
  • 5,073
  • 7
  • 41
  • 73
2

if anyone still has problems acessing messages when using custom callbacks (ex. login in via ajax):

app.post('/login', function(req, res, next) {
  passport.authenticate('local', function(err, user, info) {
    if(err) { return res.redirect('/info'); }
    if(!user) { return res.json(info); }
    req.logIn(user, function(err) {
      if(err) { return next(err); }
      return res.json(req.body.user);
    })
  })(req,res,next);
})

that info variable in passport.authenticate will hold the values you set as 'message' in your strategy:

    const authenticateUser = async (email, password, done) => {
        const user = await findUserByEmail(email);
        console.log(user);
        if( user == null ) {
            return done(null, false, { message: 'Nenhum usuário com este email.'});
        }
        try {
            if (await bcrypt.compare(password, user.password)){
                return done(null, user);
            } else {
                return done(null, false, { message: 'Senha incorreta.' })
            }
        } catch (e) {
            done(e);
        }
    }

in my case, 'Nenhum usuário com este email.' and 'Senha incorreta.'

guites
  • 76
  • 1
  • 4
1

Good Question.

I found some working code that sends flash message like this:

router.use(function(req, res, next){
    res.locals.errors = req.flash("error");
    next();
})

In EJS

    <% errors.forEach(function(error) { %>
        <div class="alert alert-danger" role = "alert">
            <%= error %>
        </div>

    <% }) %>

This might help.

res.locals

An object that contains response local variables scoped to the request, and therefore available only to the view(s) rendered during that request / response cycle (if any). Otherwise, this property is identical to app.locals.

This property is useful for exposing request-level information such as the request path name, authenticated user, user settings, and so on.

-express docs on res.locals

Community
  • 1
  • 1
jack blank
  • 5,073
  • 7
  • 41
  • 73