为什么在每个请求上执行passport.serializeUser? [英] Why is passport.serializeUser executed on each request?

查看:356
本文介绍了为什么在每个请求上执行passport.serializeUser?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用passport.js + passport-facebook-token来保护我的API构建与Strongloop的Loopback Framework。

I am using passport.js + passport-facebook-token to secure my API build with Strongloop's Loopback Framework.

为什么护照会在其后再次序列化反序列化用户已成功反序列化?每个请求都会调用passport.authenticate方法!我做错了什么?

Why is passport serializing the deserialized user again after it has successfully been deserialized? Also the passport.authenticate method is called on every request! What am I doing wrong?

这是节点的日志:

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


推荐答案

关于为什么的问题每个请求都会调用passport.authenticate ,这是因为您可能在任何路由逻辑发生之前将其定义为中间件。

Regarding your question about why passport.authenticate is called on every request, it is because you defined it as a middleware, probably before any routing logic happens.

如果你在你的应用上有私人公开部分,你可以这样做:

If you have private and public sections on your app, you could do something like that :

// 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");
   }
});

现在,如果您有多个私有部分,您可能会发现它为每个私人部门做同样的事情有点不可思议。
您可以定义一个自定义函数来检查用户是否经过身份验证,并允许请求继续进行。
类似

Now, if you have multiple private sections, you'll probably find it a bit tidious to do the same thing for each private section. You could define a custom function that will check if the user is authenticated, and allow the request to proceed if he is. Something like

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

现在,如果您的应用只有私有通过将其定义为中间件(但不能通过定义 passport.authenticate 本身,可以避免重复调用 isThisGuyAuthenticated )中间件!);

Now, if your app only has private sections, you could avoid repeating calls to isThisGuyAuthenticated by defining it as middleware (but not by defining passport.authenticate itself as a middleware !);

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

是cl耳朵?

编辑:我错误地将中间件放在/ auth端点之前。确保它放在

EDIT : I mistakenly put the middleware before the "/auth" endpoint. Make sure it's placed after

这篇关于为什么在每个请求上执行passport.serializeUser?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆