24

所以我使用本地护照和快递来处理用户登录。到目前为止,我已经能够在使用用户名的同时成功登录,但是用户名很难记住,我个人认为它们不应该用于处理用户,所以我尝试修改护照上提供的示例策略-本地页面通过电子邮件确认用户,但代码不起作用。

我对电子邮件的策略是:

passport.use(new LocalStrategy(function(email, password, done) {
  User.findOne({ email: email }, {}, function(err, user) {
    if (err) { return done(err); }
    if (!user) { return done(null, false, { message: 'Unknown user ' + e }); }
    user.comparePassword(password, function(err, isMatch) {
      if (err) return done(err);
      if(isMatch) {
        return done(null, user);
      } else {
        return done(null, false, { message: 'Invalid password' });
      }
    });
  });
}));

它源于此策略:

//The login strategy
passport.use(new LocalStrategy(function(username, password, done) {
  User.findOne({ username: username }, function(err, user) {

    if (err) { return done(err); }
    if (!user) { return done(null, false, { message: 'Unknown user ' + username }); }
    user.comparePassword(password, function(err, isMatch) {
      if (err) return done(err);
      if(isMatch) {
        return done(null, user);
      } else {
        return done(null, false, { message: 'Invalid password' });
      }
    });
  });
}));

所以用户名策略工作得很好,但电子邮件不是。我什至在用户名和电子邮件策略中都留下了一个 console.log() 来查看策略返回了什么。用户名策略返回用户的所有信息,而电子邮件策略返回

错误的

. 我不知道该站点为什么要这样做,到目前为止我所看到的解决方案都没有工作。

我在另一篇文章中看到的一个解决方案建议我只使用

 findOne({email: email}, function(err, user){
});

选择使用电子邮件登录以查找用户,但它根本没有工作。

这是我用来获取用户输入的 Jade 文件:

extends layout

block content
    h1 Login

    form(action= '/login', method='post')
        p Email
            br
            input#email(type='text',value='',placeholder='@',name='email')
        p Password
            br
            input#password(type='password',value='',placeholder='Password',name='password') 
        input(type='submit') Submit

这是 POST 输入:

// POST /login
//   This is an alternative implementation that uses a custom callback to
//   acheive the same functionality.
exports.postlogin = function(req, res, next) {
  passport.authenticate('local', function(err, user, info) {
    if (err) { return next(err) }
    if (!user) {
      req.session.messages =  [info.message];
      return res.redirect('/login')
    }
    req.logIn(user, function(err) {
      if (err) { return next(err); }
      return res.redirect('/');
    });
  })(req, res, next);
};

这到底是怎么回事?使用电子邮件,它应该可以完美运行。另外,既然我还是在问一个问题,那么在有人注册后如何确认电子邮件?

4

4 回答 4

56

在我看来,您刚刚将 LocalStrategy 回调中的参数名称更改为“电子邮件”。Passport 不会自动知道该字段名为电子邮件,但您必须告诉它。

默认情况下,LocalStrategy 期望在名为 username 和 password 的参数中找到凭据。如果您的站点希望以不同的方式命名这些字段,则可以使用选项来更改默认值。

passport.use(new LocalStrategy({
    usernameField: 'email',
    passwordField: 'passwd'
  },
  function(username, password, done) {
    // ...
  }
));

来源

于 2013-08-09T07:30:13.563 回答
4

如果您是 NestJs 的新手,并且想知道如何实现上述目标。您可以像这样在方法中传递配置选项super()

super({ 
  usernameField: 'email',
  passwordField: 'password'
})

来源

于 2021-04-02T08:17:54.340 回答
2

对于那些无法使用上述解决方案(如我)的人来说,请尝试以下方法:

passport.use(
  new LocalStrategy(
    {
      passReqToCallback: true,
    },
    (request, username, password, next) => {
      User.findOne({ email: username })
      ...

包版本(截至今天):护照:“^0.4.1”,护照本地:“^1.0.0”

于 2020-04-24T22:52:06.067 回答
-1

护照理解起来有点复杂。我有同样的问题,我所做的是在我看来(.ejs)而不是将输入命名为“电子邮件”,我只是将其重命名为“用户名”,因为这是护照所期望的。

<label for="email">Email</label>
<div class="form-group">
 <input class="form-control" type="email" name="**username**" placeholder="Email" required>
于 2017-10-27T16:28:57.373 回答