Используйте несколько локальных стратегий в PassportJS.

StackOverflow https://stackoverflow.com//questions/20052617

  •  26-12-2019
  •  | 
  •  

Вопрос

Я пытаюсь использовать несколько ЛОКАЛЬНЫХ стратегий с PassportJS.Я не пытаюсь использовать local, Facebook, Gmail и т. д.У меня есть два набора пользователей, хранящихся в отдельных объектах, и я хочу использовать локальную стратегию для аутентификации обоих.В нынешнем виде я не могу использовать одну и ту же локальную стратегию для обоих, потому что у них разные свойства объектов, что заставляет меня запрашивать разные объекты.Есть какой-либо способ сделать это?ИЛИ любые предложения по этому поводу будут очень признательны.

Это было полезно?

Решение

Я не думаю, что это возможно, потому что, насколько я понимаю, вам нужен какой-то метод «передачи» запроса второй стратегии, когда первая не удалась, и я не верю, что это возможно.

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

В качестве простого примера (с использованием Mongoose в качестве примера базы данных):

passport.use(new LocalStrategy(function(username, password, done) {
  Model1.findOne({ username : username }, function(err, user) {
    // first method succeeded?
    if (!err && user && passwordMatches(...)) {
      return done(null, user);
    }
    // no, try second method:
    Model2.findOne({ name : username }, function(err, user) {
      // second method succeeded?
      if (! err && user && passwordMatches(...)) {
        return done(null, user);
      }
      // fail! 
      done(new Error('invalid user or password'));
    });
  }); 
}));

Для сериализации/десериализации вам может потребоваться сохранить некоторое свойство в user объект, к которому вы переходите done чтобы указать, какая модель необходима для десериализации пользователя.

Другие советы

Вы можете имя ваши местные стратегии для их разделения.

// use two LocalStrategies, registered under user and sponsor names

      // add other strategies for more authentication flexibility
  passport.use('user-local', new LocalStrategy({
      usernameField: 'email',
      passwordField: 'password' // this is the virtual field on the model
    },
    function(email, password, done) {
      User.findOne({
        email: email
      }, function(err, user) {
        if (err) return done(err);

        if (!user) {
          return done(null, false, {
            message: 'This email is not registered.'
          });
        }
        if (!user.authenticate(password)) {
          return done(null, false, {
            message: 'This password is not correct.'
          });
        }
        return done(null, user);
      });
    }
  ));

    // add other strategies for more authentication flexibility
    passport.use('sponsor-local', new LocalStrategy({
            usernameField: 'username',
            passwordField: 'password' // this is the virtual field on the model
        },
        function(username, password, done) {
            Sponsor.findOne({
                'primaryContact.username': username
            }, function(err, sponsor) {
                if (err) return done(err);

                if (!sponsor) {
                    return done(null, false, {
                        message: 'This email/username is not registered.'
                    });
                }
                if (!sponsor.authenticate(password)) {
                    return done(null, false, {
                        message: 'This password is not correct.'
                    });
                }
                return done(null, sponsor);
            });
        }
    ));
.

Последний код контроллера обращается к ним по имени.

/**
 * User Login
 */
exports.loginUser = function (req, res, next) {
    passport.authenticate('user-local', function(err, user, info) {
        var error = err || info;
        if (error) return res.json(401, error);

        req.logIn(user, function(err) {

            if (err) return res.send(err);
            res.json(req.user.userInfo);
        });
    })(req, res, next);
};

/**
 * Sponsor Login
 */
exports.loginSponsor = function (req, res, next) {
    passport.authenticate('sponsor-local', function(err, sponsor, info) {
        var error = err || info;
        if (error) return res.json(401, error);

        req.logIn(sponsor, function(err) {
            if (err) return res.send(err);
            res.json(req.sponsor.profile);
        });
    })(req, res, next);
};
.

Позже, когда придет время для сериализации вас пользователя, вы можете сделать что-то вроде этого.

// serialize
passport.serializeUser(function(user, done) {            
  if (isUser(user)) {
    // serialize user
  } else if (isSponsor(user)) {
    // serialize company
  }
});
.

Вы можете использовать что-то вроде этого для нескольких местных стратегий

passport.use('local.one', myLocalStrategy1);
passport.use('local.two', myLocalStrategy2);
passport.use('local.three', myLocalStrategy3);

...

app.get('/login/s1', passport.authenticate('local.one');
app.get('/login/s2', passport.authenticate('local.two');
app.get('/login/s3', passport.authenticate('local.three');
.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top