Почему паспорт.serializeUser выполняется при каждом запросе?

Я использую паспорт.js + паспорт-facebook-токен для защиты моей сборки API с помощью Strongloop Loopback Framework.

Почему паспорт снова сериализует десериализованного пользователя после того, как он был успешно десериализован? Также при каждом запросе вызывается методpassport.authenticate! Что я делаю не так?

Вот журнал узла:

deserializeUser, id: XXXXXXXXXXXXXXXX
User found.
serializeUser, id: XXXXXXXXXXXXXXXX
GET /api/events?access_token=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 304 182ms

Вот js-код:

passport.use(new FacebookTokenStrategy({
    clientID: XXXXXXXXXXXXXXXX,
    clientSecret: 'XXXXXXXXXXXXXXXXXXXXXXXXXXXX'
  },
  function(accessToken, refreshToken, profile, done) {
    //check user table for anyone with a facebook ID of profile.id
    User.findOne({
      'facebookId': profile.id
    }, function(err, user) {
      if (err) {
        return done(err);
      }
      if (user) {
        console.log("User found.");
        return done(err, user);
      } else {
        console.log("User not found.");
        User.create({
          email: profile.emails[0].value,
          facebookId: profile.id,
          password: 'secret'
        }, function(err, user) {
          console.log(user.id);
          console.log(user.email);
          console.log(user.facebookId);
          console.log("User created");
          return done(err, user);
        });
      }
    });
  }));

passport.serializeUser(function(user, done) {
  console.log('serializeUser, id: ' + user.facebookId);
  done(null, user.facebookId);
});

passport.deserializeUser(function(id, done) {
  console.log('deserializeUser, id: ' + id);
  User.findOne({
    'facebookId': id
  }, function(err, user) {
    if (!err) {
      done(null, user);
    } else {
      done(err, user);
    }
  });
});

person electronix384128    schedule 22.07.2014    source источник
comment
Не могли бы вы показать код, в котором вы определяете промежуточное программное обеспечение, обрабатывающее вашу аутентификацию? Должно получиться что-то вроде passport.authenticate("facebook", function ....). Если вы сделали что-то вроде app.get("/*", passport.authenticate()), все работает, как и ожидалось.   -  person Waldo Jeffers    schedule 22.07.2014
comment
Это единственный loc, который добавляется для этого: app.use(passport.authenticate('facebook-token'));   -  person electronix384128    schedule 22.07.2014
comment
хм, хорошо, я вижу. но я так понимаю, что его следует добавить как промежуточное программное обеспечение, поскольку оно защищает мой API от несанкционированного доступа... где было бы правильно добавить эту строку? или что вы предлагаете?   -  person electronix384128    schedule 22.07.2014


Ответы (1)


Что касается вашего вопроса о том, почему passport.authenticate вызывается при каждом запросе, это потому, что вы определили его как промежуточное программное обеспечение, возможно, до того, как произойдет какая-либо логика маршрутизации.

Если в вашем приложении есть частные разделы и public, вы можете сделать что-то вроде этого:

// Define a specific that will handle authentication logic
app.get("/auth", passport.authenticate('facebook-token',function(){...});

// Public sections which do not require authentication
app.get("/public1",...);
app.post("/public2",...);

// Private sections which do require authentication
app.get("/private1", function(req,res,next){
   if (req.isAuthenticated()){ // Check if user is authenticated
       // do things...
   }else{ // Wow, this guy is not authenticated. Kick him out of here !
       res.redirect("/auth");
   }
});

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

function isThisGuyAuthenticated(req,res,next){
   if (req.isAuthenticated()){
      return next(); // Ok this guy is clean, please go on !
   }else{
      res.redirect("/auth"); // This guy is shady, please authenticate !
   }
}

И используйте его как:

app.get("/private1",isThisGuyAuthenticated, doCrazySecretStuff); // doCrazySecretStuff will not be called if the user is not authenticated
app.get("/private2", isThisGuyAuthenticated, getCocaColaRecipe);
app.get("/private3", isThisGuyAuthenticated, flyToMars);
app.get("/public", showInfo); // showInfo will be called whether the user is authenticated or not

Теперь, если ваше приложение имеет только частные разделы, вы можете избежать повторных вызовов isThisGuyAuthenticated, определив его как промежуточное ПО (но не определяя сам passport.authenticate как промежуточное ПО!);

// Endpoint that will be hit is the user is redirected to /auth
// BEWARE it needs to be above the middleware, otherwise you'll end up with an infinite redirection loop
app.get("/auth", passport.authenticate('facebook-token',function(){...});

// Middleware that will be called on every request
app.use(isThisGuyAuthenticated);

// You app's endpoints
app.get("/private1", doCrazySecretStuff); // doCrazySecretStuff will not be called if the user is not authenticated
app.get("/private2", getCocaColaRecipe);
app.get("/private3", flyToMars);

Это ясно?

EDIT: я по ошибке поместил промежуточное ПО перед конечной точкой "/auth". Убедитесь, что он размещен после

person Waldo Jeffers    schedule 22.07.2014
comment
Очень хороший ответ! Большое спасибо, я думаю, теперь все ясно, позвольте мне попробовать, и я проверю это как ответ! - person electronix384128; 22.07.2014
comment
Пожалуйста. Дайте мне знать, если у вас есть какие-либо проблемы. И, пожалуйста, проверьте мое редактирование, я изначально сделал ужасную ошибку. - person Waldo Jeffers; 22.07.2014
comment
В яблочко. И я исправил небольшую опечатку в функции /auth...! Но это работает. Теперь только первый запрос к /auth занимает ~ 200 мс, другие запросы используют существующий сеанс и безумно быстро (‹ 10 мс) :) THX - person electronix384128; 22.07.2014
comment
Можем мы поговорить, у меня есть некоторые сомнения относительно этого ответа? - person Suraj Jain; 07.01.2018