Sử dụng PassportJS, làm cách nào để chuyển các trường biểu mẫu bổ sung vào chiến lược xác thực cục bộ?


98

Tôi đang sử dụng passportJS và tôi muốn cung cấp nhiều hơn chỉ req.body.usernamereq.body.passwordcho chiến lược xác thực của mình (passport-local).

Tôi có 3 lĩnh vực có dạng: username, password, &foo

Làm cách nào để truy cập req.body.footừ chiến lược địa phương của tôi, giống như sau:

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);

      });
    }
));

Tôi đang gọi điều này bên trong tuyến đường của mình (không phải là phần mềm trung gian tuyến đường) như vậy:

  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);

  });

Câu trả lời:


179

Có một passReqToCallbacktùy chọn mà bạn có thể bật, như sau:

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

Khi nào, set reqtrở thành đối số đầu tiên cho lệnh gọi lại xác minh và bạn có thể kiểm tra nó theo ý muốn.


8
Điều đó hoạt động tốt, cảm ơn. Có passReqToCallbacktrong hướng dẫn không? Tôi không thấy nó.
k00k

2
Chưa. Tôi đang cố gắng thêm các tính năng / tùy chọn mới vào hướng dẫn.
Jared Hanson

Cảm ơn, lưu lại cho tôi nhiều rắc rối
binarygiant

9
Điều này thực sự hữu ích cho việc triển khai xác thực nhiều người thuê / nhiều người thuê nhà, nhưng không xuất hiện trong các tìm kiếm trên google của tôi. Hy vọng rằng bình luận của tôi sẽ giúp mọi người tìm ra câu trả lời này trong tương lai.
Kris Dahl

Điều này rất hữu ích. Nhưng có thể đặt usernameFieldtheo một điều kiện không? Tôi có hai lựa chọn: một là email và hai là số điện thoại. và bảng đăng nhập chứa hai trường này cùng với mật khẩu.
Mathew John

1

Trong hầu hết các trường hợp phổ biến, chúng tôi cần cung cấp 2 tùy chọn để đăng nhập

  • với email
  • với điện thoại di động

Thật đơn giản, chúng ta có thể sử dụng tên người dùng đã nộp chung và truy vấn $ hoặc bằng hai tùy chọn, tôi đã đăng các đoạn mã sau đây, nếu một số người có cùng câu hỏi.

Chúng tôi cũng có thể sử dụng 'passReqToCallback' cũng là lựa chọn tốt nhất, cảm ơn @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
        });
    }
}));
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.