Следующая функция, не вызываемая при сбое аутентификации по паспорту

#node.js #passport.js

#node.js #passport.js

Вопрос:

Я использую Passport.js с помощью Express

Это стратегия:

 passport.use(
  new Strategy(async function(username, password, done) {
    try {
      var user = await db.findOne("users", { username: username });
      if (!user) {
        console.log(`Incorrect username`.red);
        return done(null, false, { message: "Incorrect username" });
      }
    } catch (error) {
      return done(error);
    }

    if (username !== user.username) {
      return done(null, false, { message: "Icorrect user!" });
    }
    if (password !== user.password) {
      // console.log("Incorrect Password");
      return done(null, false, { message: "Icorrect password!" });
    }
    return done(null, user, { message: "user lorem ipsum" });
  })
);
  

При входе в систему выполняется аутентификация по post-запросу:

 app.post(
    "/Login",
    // checkCred,
    passport.authenticate("local", {
      failureFlash: true,
      successFlash: true
    }),
    // The following function is only invoked if authentication succeeded
    (req, res) => {
      console.log(`Called`.red);
      console.log(`CAAALEEEEE`.green);

      res.send(
        JSON.stringify({
          status: "ok",
          message: "OK",
          redirect: "/User",
          user: req.user ? req.user : "user not found in request"
        })
      );
      // res.redirect("/User");
    }
  );
  

Если аутентификация не прошла, вторая (req, res) => { функция никогда не вызывается.
Как заставить passport вызывать функцию next (), чтобы я мог вернуть ответ пользователю?

Ответ №1:

По умолчанию passport.authenticate() возвращает 401 Unauthorized для неудачного входа в систему или переходит к следующему промежуточному программному обеспечению с req.user заполненным. Вы можете переопределить поведение по умолчанию несколькими способами:

  1. с successRedirect или failureRedirect параметрами для authenticate()
  2. предоставьте пользовательский обратный вызов на authenticate() , где вы делаете любые перенаправления, которые вы хотите, и вызываете вручную req.logIn()

В вашем случае я бы полностью удалил обработчик (req, next) и использовал successRedirect и failureRedirect вот так

 app.post("/Login", passport.authenticate("local", {
  successRedirect: "/User",
  failureRedirect: "/Login",
  failureFlash: true,
  successFlash: true,
}));
  

Не забудьте добавить необходимые пакеты для отображения флэш-сообщений.

Комментарии:

1. Я хотел бы вернуть пользователю пользовательское сообщение, информирующее его о сбое входа в систему.

2. @Hairi failureFlash: true отображает сообщение по умолчанию для стратегии аутентификации. Вы можете передать пользовательское сообщение, изменив логическое значение на строку, подобную этой failureFlash: "Invalid username or password" . Не забывайте отображать flash-сообщения при рендеринге своих страниц.