Как правильно сообщить о неверном входе в систему с помощью Express и PassportJS? - PullRequest
4 голосов
/ 13 марта 2012

Я успешно внедрил passport-local в свое веб-приложение Express / Mongoose, но мне не удается понять, как правильно отобразить сообщение об ошибке при входе в систему.

Вот мой маршрут входа в систему:

app.get('/login', function(req, res) {
   res.render('user/login', {
   });
});

С таким маршрутом, как я могу сообщить о неверном логине? Если вход успешен, он запишет id / username в объект req.user, но это не поможет мне в маршруте "GET /login", потому что в случае успеха вы будете перенаправлены на страницу, на которую хотите перейти .

Это означает, что req.user всегда будет undefined, когда вы GET войдете на страницу входа.

Я хочу, чтобы я мог написать сообщение, говорящее что-то вроде: «Эй, неверный логин!» когда происходят следующие вещи:

  1. Пользователь не существует.
  2. Предоставленный пароль не совпадает, но пользователь существует.

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

Когда я реализовал LocalStrategy, я использовал этот код:

passport.use(new LocalStrategy({
    usernameField: 'email'
},
function(email, password, fn) {
  User.findOne({'login.email': email}, function(err, user) {
    // Error was thrown.
    if (err) {
      return fn(err);
    }

    // User does not exist.
    if (!user) {
      return fn(null, false);
    }

    // Passwords do not match.
    if (user.login.password != utility.encryptString(user.login.salt + password)) {
      return fn(null, false);
    }

    // Everything is good.
    return fn(null, user);
  });
}
));

Как видите, есть некоторые проблемы, но именно так автор PassportJS настроил свое приложение. Как мы можем получить доступ к тому, что возвращает Стратегия?

Например, если он выдаст ошибку, что мне вообще нужно вызывать, чтобы получить доступ к err?

Спасибо.

Ответы [ 2 ]

17 голосов
/ 27 марта 2012

В последней версии Passport я добавил поддержку флеш-сообщений, которые упрощают выполнение ваших запросов.

Теперь вы можете указать третий аргумент для done, который может содержать сообщение об ошибке. Например:

if (user.login.password != utility.encryptString(user.login.salt + password)) {
  return fn(null, false, { message: 'yo, invalid login!' });
}

Затем установите failureFlash на true в качестве опции на authenticate().

passport.authenticate('local', { successRedirect: '/',
                                 failureRedirect: '/login',
                                 failureFlash: true });

В этом случае, если аутентификация не пройдена, сообщение будет установлено во флэш-памяти, и оно будет готово для его обработки при повторном отображении страницы входа.

Пользовательские обратные вызовы также прекрасно. Встроенные опции упрощают выполнение обычных задач.

Кроме того, мне любопытно: вы упомянули, что с образцом есть проблемы. Как вы думаете, что должно быть улучшено? Я хочу сделать примеры как можно лучше. Спасибо!

(Подробнее см. комментарий к вопросу № 12).

10 голосов
/ 14 марта 2012

Вы можете использовать пользовательские функции обратного вызова или промежуточного программного обеспечения для большего контроля.См. Примеры Аутентификация в руководстве.

Например, пользовательский обратный вызов может выглядеть следующим образом:

app.get('/login', function(req,res,next) {
    passport.authenticate('local', function(err,user) {
            if(!user) res.send('Sorry, you\'re not logged in correctly.');
            if(user) res.send('Skeet skeet!');
    })(req,res,next);
});

В качестве альтернативы вывсегда может перенаправить оба ответа:

app.get('/login', 
    passport.authenticate('local', { successRedirect: '/winner',
                                     failureRedirect:'/loser' }));

Или перенаправить ошибку с помощью простого промежуточного программного обеспечения:

app.get('/login', ensureAuthenticated,
    function(req,res) {
                // successful auth
                // do something for-the-win
    }
);

    // reusable middleware
    function ensureAuthenticated(req,res,next) {
        if(req.isAuthenticated()) {return next();}
        res.redirect('/login/again'); // if failed...
    }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...