如何闪现来自 Passport.js 的消息?

How to flash a message from Passport.js?

我已经使用 express 和 passport js 创建了登录和注册。 我想为错误的密码或电子邮件添加消息。

在我的 index.js(主要)中添加了护照和正文解析器中间件,并引用了路由:

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);

并且我创建了护照配置:

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);
    });
  });
};

还为其添加了一条路线:

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

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

successRedirect 和 failureRedirect 工作正常,但没有给我任何错误。我在视频中的 youtube 视频上做到了,但在我的代码中却没有。

连接闪光灯的配置:

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

您的代码没有问题,它只是您使用的 express 版本。来自 Passportjs Flash 消息文档,

注意:使用即显消息需要 req.flash() 函数。 Express 2.x 提供了此功能,但它已从 Express 3.x 中删除。在使用 Express 3.x.

时,建议使用 connect-flash 中间件来提供此功能

因此您需要按照推荐安装connect-flash express 中间件。

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());
});

有了 flash 中间件,所有请求都将具有可用于 flash 消息的 req.flash() 函数。

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') });
});

这可能对您有所帮助。

首先,我不太明白配置的意义 app.use() 需要。只需在您的配置中像这样在 app.use() 中调用 flash() 方法。

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

您缺少的是 req.flash("error")。因为当发生故障时,passport 将 message 对象作为 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.

此代码在我这边运行并传递 req.flash() 消息。

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"),
    });
});

在视图方面,现在您可以访问 error 对象,因此可以将其用于视图。 在我的 error.hbs 车把视图中,我这样做了。

error.hbs

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

希望这对您有所帮助。

显示成功/失败闪现消息的更简单途径:

router.post('/login', passport.authenticate("local", 
    {
        successRedirect: "/",
        failureRedirect: "/auth/login",
        successFlash: true,            
        failureFlash: true,
        successFlash: 'Succesfu1!',
        failureFlash: 'Invalid username or passwerd.'
    })
);

要 return 不使用 flash 选项的消息,请像这样更改 post 方法

router.post('/users/signin', function (req, res, next) {
  passport.authenticate('local', function (err, user, info) {
    if (err) {
      return next(err);
    }
    if (!user) {
      // *** Display message without using flash option
      res.status(500).send({ message: info.message });
    } else {
      // *** Display message without using flash option
      res.status(200).send({ message: 'success' });
    }
  })(req, res, next);
});