node.jspassport.jslocomotivejs

How to display flash message on login with passport ldapauth


So, my app uses a login through a ldap server. Once it's authenticated, I login or create a user on my database, and then proceed with my app.

However, I'm trying to display a flash message when the user fails to login with ldap (invalid credentials or whatever), but I can't get to do it the way the documentation says.

I'm using locomotive js as framework, so I'd like to keep using this routing :

routes.js

this.match('/', 'pages#homepage',{ via: 'GET' });   

this.match('login', passport.authenticate('ldapauth', {
  successRedirect : '/dashboard', 
  failureRedirect : '/', 
  failureFlash : true 
})  ,{ via: 'POST' });

pagesController.js

pagesController.homepage = function() {
  this.title = 'title';
  this.render('',{messageRedirect: this.req.flash('messageRedirect')});
};

.ejs

<% if (messageRedirect.length>0) { %>
    <div class="alert alert-danger"><%= messageRedirect %></div>
<% } %> 

passport.js

passport.use(new LdapStrategy( {

server: {
    url: config.ldap.url,
    bindDn:  config.ldap.bindDn,
    bindCredentials: config.ldap.bindCredentials,
    searchBase: config.ldap.searchBase,
    searchFilter: config.ldap.searchFilter,
    searchAttributes: config.ldap.searchAttributes,
    tlsOptions: {
        ca: [
            fs.readFileSync(config.ssl.cert)
        ],
        rejectUnauthorized: false
    }
}

}, function(ldapUser, done){

var queryUser = {...};

    user.getByUsername(queryUser, function(err,res){

        if (err) {
          return(err,null);
        }

        // if we don't find the user, it's his first attempt to login and we have to add him in the base
        if(res.length==0){

            user.create( queryUser, function(err,res){
                if (err){
                    return (err,null);
                }
            });

            var returnUser = {...};
            return done(null,returnUser,{
            message: 'Created and logged in Successfully'
            });

        }

        else{

            var returnUser = {...};
          return done(null, returnUser, {
            message: 'Logged In Successfully'
          });
        }
    });
   }
));

The issue I'm having is that if the ldap login fail, the verify callback is not called so I can't display login failures through it. The flash otherwise works, since it works on several other pages. It even works on this page (e.g. when the user tries to access a page without being connected), but just not for login failure. I tried a lot of other stuff, but this is the only part that i'm kinda sure of.

I can introduce an '/again' route to display an error, but I'd like to have the ldap one, that should be more precise.


Solution

  • passport-ldapauth sets the messages when LDAP authentication fails, and Passport.js then puts the message to req.flash using error as the key if type is not defined (which is the case with passport-ldapauth).

    You can customize the messages when calling passport.authenticate. If using Microsoft AD, you can customize some additional messages as mentioned in the readme

    So, to get the failure messages this should work:

    this.render('', {
      messageRedirect : this.req.flash('messageRedirect'),
      messageLdapError : this.req.flash('error')
    });