2012-03-13 3 views
2

Я успешно реализовал паспорт-локальный сайт в своем веб-приложении Express/Mongoose, но у меня возникли проблемы с выяснением того, как правильно отобразить неверное сообщение для входа.Как я могу сообщить неверный логин правильно с помощью Express и PassportJS?

Вот мой маршрут Логин:

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

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

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

Я хочу, чтобы иметь возможность написать сообщение с надписью «yo, invalid login!» когда происходят следующие события:

  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?

Спасибо.

ответ

10

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

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

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... 
    } 
+0

Хорошо, пользовательский подход обратного вызова выглядит так, как будто он будет работать. Благодарю. Как бы обе альтернативные решения выполняли одно и то же? Не могли бы вы сделать пример перенаправления успеха/отказа в запросе POST? Это то, что я делаю. И второй альтернативный вариант - это стандартный способ принудительного входа в систему для доступа к странице? Например, это то, что вы могли бы разместить на странице, на которую вы хотели бы контролировать доступ (профиль пользователя и т. Д.). Я собираюсь отметить вас как ответ для пользовательского обратного вызова. – AntelopeSalad

+0

Я принял ваш вопрос как «как я могу ответить на успех или неудачу аутентификации?», И эти три метода - это разные способы сделать это. Для альтернатив вы просто отправляете клиента на другой маршрут для обработки ответа ... поскольку я не знаю специфики вашей реализации, вам решать, что лучше. Да, вариант 3 - отличный способ обеспечить аутентификацию для страниц, требующих аутентификации. –

17

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

Теперь вы можете предоставить третий аргумент 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 }); 

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

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

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

(Для получения дополнительной информации см. Это comment по вопросу № 12).

+0

Сбой вспышки делает его намного проще. Однако я заметил, что любой 'err', переданный' done' или OP 'fn' должен быть нулевым или ложным для этой работы, занял у меня минуту, чтобы понять это. – JohnnyCoder