PassportJSを使用して、追加のフォームフィールドをローカル認証戦略にどのように渡しますか?


98

私はpassportJSを使用していると私はちょうどより多く供給したいんだreq.body.usernamereq.body.password、私の認証戦略(パスポートローカル)にします。

私は3つのフォームフィールドを持っています:usernamepassword、&foo

req.body.foo次のようなローカル戦略からアクセスするにはどうすればよいですか。

passport.use(new LocalStrategy(
  {usernameField: 'email'},
    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' });
        }
        if (password != 1212) {
          return done(null, false, { message: 'Invalid password' });
        }
        console.log('I just wanna see foo! ' + req.body.foo); // this fails!
        return done(null, user, aToken);

      });
    }
));

私はこれを私のルート内で(ルートミドルウェアとしてではなく)次のように呼んでいます:

  app.post('/api/auth', function(req, res, next) {
    passport.authenticate('local', {session:false}, function(err, user, token_record) {
      if (err) { return next(err) }
      res.json({access_token:token_record.access_token});
   })(req, res, next);

  });

回答:


179

次のpassReqToCallbackように、有効にできるオプションがあります。

passport.use(new LocalStrategy(
  {usernameField: 'email', passReqToCallback: true},
  function(req, email, password, done) {
    // now you can check req.body.foo
  }
));

すると、set reqがverifyコールバックの最初の引数になり、必要に応じて検査できます。


8
ありがとうございます。あるpassReqToCallbackガイドに?見なかった。
k00k

2
未だに。ガイドに新しい機能/オプションを追加するのが遅れています。
Jared Hanson

おかげで、私は多くの問題を保存
binarygiant

9
これはマルチテナント/マルチテナント認証を実装するのに非常に役立ちますが、Google検索では表示されませんでした。うまくいけば、私のコメントが将来人々がこの答えを見つけるのに役立つでしょう。
Kris Dahl、2016年

これは非常に役立ちます。しかしusernameField、条件に応じて設定することは可能ですか?2つのオプションがあります。1つは電子メールで、もう1つは電話番号です。ログインテーブルには、これら2つのフィールドとパスワードが含まれています。
Mathew John

1

最も一般的なケースでは、ログインに2つのオプションを提供する必要があります

  • メールで
  • モバイルで

その単純な、私たちは一般的なファイルされたユーザー名を取得し、$または2つのオプションでクエリを実行できます。

「passReqToCallback」を使用することもできます。これは、@ Jared Hanson氏に感謝します。

passport.use(new LocalStrategy({
    usernameField: 'username', passReqToCallback: true
}, async (req, username, password, done) => {
    try {
        //find user with email or mobile
        const user = await Users.findOne({ $or: [{ email: username }, { mobile: username }] });

        //if not handle it
        if (!user) {
            return done(null, {
                status: false,
                message: "That e-mail address or mobile doesn't have an associated user account. Are you sure you've registered?"
            });
        }

        //match password
        const isMatch = await user.isValidPassword(password);
        debugger
        if (!isMatch) {
            return done(null, {
                status: false,
                message: "Invalid username and password."
            })
        }

        //otherwise return user
        done(null, {
            status: true,
            data: user
        });
    } catch (error) {
        done(error, {
            status: false,
            message: error
        });
    }
}));
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.