Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to flash a message from Passport.js?

I've created login and register with express and passport js. I want to add a message for wrong password or email.

in my index.js (main) added passport and body parser middleware with referring to the routes :

app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());

// route files
let index = require("./routes/index");
let auth = require("./routes/auth");
app.use("/", index);
app.use("/auth", auth);

and I created passport configuration :

const LocalStrategy = require("passport-local").Strategy;
const User = require("../models/User");
const config = require("../config/database");
const bcrypt = require("bcryptjs");

module.exports = function(passport) {
  // Local Strategy
  passport.use(
    new LocalStrategy(
      {
        usernameField: "email",
        passwordField: "password"
      },
      (username, password, done) => {
        // Match Email
        let query = { email: username };
        User.findOne(query, function(err, user) {
          if (err) throw err;
          if (!user) {
            return done(null, false, { message: "No user found" });
          }

          // Match Password
          bcrypt.compare(password, user.password, function(err, isMatch) {
            if (err) throw err;
            if (isMatch) {
              return done(null, user);
            } else {
              return done(null, false, { message: "Wrong password" });
            }
          });
        });
      }
    )
  );

  passport.serializeUser(function(user, done) {
    done(null, user.id);
  });

  passport.deserializeUser(function(id, done) {
    User.findById(id, function(err, user) {
      done(err, user);
    });
  });
};

also added a route for it :

// Login Process
router.post("/login", (req, res, next) => {
  passport.authenticate("local", {
    successRedirect: "/",
    failureRedirect: "/auth/login",

    failureFlash: true
  })(req, res, next);
});

the successRedirect and failureRedirect work fine, but it doesn't give me any error. I did it on a youtube video in the video it works but in my code it doesn't.

configuration of connect flash :

const flash = require("connect-flash");
app.use(require("connect-flash")());
like image 970
Hama Saadwn Avatar asked Sep 29 '18 11:09

Hama Saadwn


People also ask

How do I use flash on my passport?

Can you use the flash? Yes. The passport guidelines don't forbid people from using the flash as long as the final outcome represents a true likeness of their appearance. This can be achieved with or without a flash, so you're fine to have yours on when you pose for your passport photo.

How do I show flash messages in node JS?

To implement flash messages in NodeJs with connect-flash module, you need to install the required dependencies using the command. Express: Required by the library connect-flash to run. Express-session: to create a session whenever a message is flashed, so that the user can be redirected to a particular page.

Should I use passport js for authentication?

Passport is a popular, modular authentication middleware for Node. js applications. With it, authentication can be easily integrated into any Node- and Express-based app. The Passport library provides more than 500 authentication mechanisms, including OAuth, JWT, and simple username and password based authentication.


2 Answers

Nothing wrong with your code, its just the version of express you are using. From the Passportjs Flash Message documentation,

Note: Using flash messages requires a req.flash() function. Express 2.x provided this functionality, however it was removed from Express 3.x. Use of connect-flash middleware is recommended to provide this functionality when using Express 3.x.

So you need to install connect-flash express middleware as it is recommended.

var flash = require('connect-flash');
var app = express();

app.configure(function() {
  app.use(express.cookieParser('keyboard cat'));
  app.use(express.session({ cookie: { maxAge: 60000 }}));
  app.use(flash());
});

With the flash middleware in place, all requests will have a req.flash() function that can be used for flash messages.

app.get('/flash', function(req, res){
  req.flash('info', 'Flash is back!')
  res.redirect('/');
});

app.get('/', function(req, res){
  res.render('index', { messages: req.flash('info') });
});

This might help you.

like image 59
Saurabh Ghewari Avatar answered Oct 12 '22 08:10

Saurabh Ghewari


First, I don't quite see the point of configuring app.use() with require. Just call the flash() method inside app.use() like this in your configuration.

var flash = require("connect-flash");
app.use(flash());

What you're missing is req.flash("error"). Because when a failure occurs passport passes the message object as error.

Passport Authenticate

Setting the failureFlash option to true instructs Passport to flash an error message using the message given by the strategy's verify callback, if any.

This code is working at my end and passing req.flash() messages.

routes.js

//route for passport strategy
    router.post("/login", passport.authenticate("local-signin", {
        failureRedirect: "/error",
        failureFlash: true,
    }));

//route for error page
router.get("/error", function(req, res, next) {
    res.render("error", {
        error: req.flash("error"),
    });
});

On the view side now you have access to error object hence can use it for view. In my error.hbs handlebars view I do this.

error.hbs

{{#if error}}
    {{error}}
//Wrong password or No User Found
{{/if}}
<p>No results to show.</p>

Hope this helps.

like image 20
Asghar Musani Avatar answered Oct 12 '22 07:10

Asghar Musani