改进node.js代码(sequelize、promises和passport)

改进node.js代码(sequelize、promises和passport),node.js,authentication,promise,sequelize.js,Node.js,Authentication,Promise,Sequelize.js,我是node.js、sequelize、蓝鸟承诺和FB认证的新手 我想用一些身份验证细节来持久化我的FB身份验证用户 在我的模型中,一个用户可以同时拥有多个身份验证(一个用于浏览器,另一个用于移动设备等)。 我需要处理这些身份验证,因此我有以下关系: hasMany(Auth); 授权归属(用户) 我写了这段代码,但我仍然在寻找一个更智能的解决方案 主要目标是向用户添加身份验证信息。 因此,在验证身份验证信息之前,我要寻找一个持久化的用户 function(accessToken, refres

我是node.js、sequelize、蓝鸟承诺和FB认证的新手

我想用一些身份验证细节来持久化我的FB身份验证用户

在我的模型中,一个用户可以同时拥有多个身份验证(一个用于浏览器,另一个用于移动设备等)。 我需要处理这些身份验证,因此我有以下关系:

hasMany(Auth); 授权归属(用户)

我写了这段代码,但我仍然在寻找一个更智能的解决方案

主要目标是向用户添加身份验证信息。 因此,在验证身份验证信息之前,我要寻找一个持久化的用户

function(accessToken, refreshToken, profile, done) {

        console.log("FacebookStrategy_function:\naccessToken: " + accessToken);

    var thatUser=null;

        User.find({
          where: {
            username: profile.username 
          },
          include: [{model: Auth}]
        }).then(function(user) {
          console.log("USER IS #1: %j", user);
          if(user!= null){  // User found in database
            console.log("User " + profile.id + "found in database");
            return user;
          }else{  // First time that user authenticate in app
          var user = User.build({
              username: profile.username,
              givenName: profile.name.givenName,
              familyName: profile.name.familyName
            });
            return user.save();
          }
        }).then(function(user) {
          console.log("USER IS #2: %j", user);
          thatUser=user;

          var auth= Auth.build({
            provider: 'facebook',
            providerId: profile.id,
            accessToken: accessToken
          });

          return user.addAuth(auth);
        }).then(function(auth){
          user=thatUser;
          console.log("USER IS #3: %j", user);
          console.log("done. user and association saved.  auth is: %j", auth);


          done(null, user); // Call FacebookEstrategy's done
        }, function(err) {
            console.log("\nsomething happened persisting user/auth " + err);
            done(err, null); // Propagate error to FacebookEstrategy
        });

      }
拥有下一个日志:

    FacebookStrategy_function: accessToken: CAACO...
    Executing (default): SELECT "Users".*, "Auths"."id" AS "Auths.id", ... WHERE     "Users"."username"='john.doe'...
    INSERT INTO "Users" ("id","username","givenName","familyName","createdAt","updatedAt") VALUES (DEFAULT,'john.doe',...)
    USER IS #1: null
    Executing (default): INSERT INTO "Users"     ("id","username","givenName","familyName","createdAt","updatedAt") VALUES (DEFAULT,'john.doe',...)
    USER IS #2: {"username":"john.doe","givenName":"John","familyName":"Doe","id":2,"updatedAt":"2014-11-09T19:12:23.250Z","createdAt":"2014-11-09T19:12:23.250Z"}
    Executing (default): SELECT * FROM "Auths" WHERE "UserId" = 2;
    Executing (default): INSERT INTO "Auths" ("id","provider","providerId","accessToken","createdAt","updatedAt","UserId") VALUES (DEFAULT,'facebook','...','CAACO...','2014-11-09 19:12:23.278 +00:00','2014-11-09 19:12:23.278 +00:00',2) RETURNING *;
    USER IS #3: {"username":"john.doe","givenName":"John","familyName":"Doe","id":2,"updatedAt":"2014-11-09T19:12:23.250Z","createdAt":"2014-11-09T19:12:23.250Z"}
    done. user and association saved.  auth is: {"provider":"facebook","providerId":"...","accessToken":"CAACO...","id":2,"UserId":2,"updatedAt":"2014-11-09T19:12:23.278Z","createdAt":"2014-11-09T19:12:23.278Z"}
对我来说,要处理的是wierd,user.addAuth(auth)返回一个auth对象。 在下一个then方法中,我希望接收一个user对象(而不是auth) 作为解决方法,我在主函数范围中使用了一个用户变量。 有没有更聪明的方法

在日志中,跟踪“USER IS#3:”显示的是没有身份验证对象的用户。 为什么?

任何纠正或改进都会很好


谢谢

如果您正在使用承诺-您可以放弃
done
回调-您只需返回承诺即可。如果您确实想要完成回调-您可以调用
.nodeify
,而不是显式调用它,尽管返回承诺还有其他好处,如未处理的拒绝跟踪

您还可以使用聚合方法而不是显式闭包范围:

function(accessToken, refreshToken, profile) {
    console.log("FacebookStrategy_function:\naccessToken: " + accessToken);
    return User.find({
      where: { username: profile.username }, include: [{model: Auth}]
    }).then(function(user) {
      console.log("USER IS #1: %j", user);
      if(user!= null){  // User found in database
        console.log("User " + profile.id + "found in database");
        return user;
      } 
      return User.build({ // first time
          username: profile.username,
          givenName: profile.name.givenName,
          familyName: profile.name.familyName
        }).save();
    }).then(function(user) {
      console.log("USER IS #2: %j", user);
      var auth= Auth.build({
        provider: 'facebook',
        providerId: profile.id,
        accessToken: accessToken
      });
      return [user, user.addAuth(auth)]; // note the array
    }).spread(function(user, auth){ // note the spread
      console.log("USER IS #3: %j", user);
      console.log("done. user and association saved.  auth is: %j", auth);
      return user;
    });
}
现在,如果允许我删除所有的
console.log
s,这会变得更短:

function(accessToken, refreshToken, profile) {
  return User.find({
      where: { username: profile.username }, include: [{model: Auth}]
  }).then(function(user) {
    return user || User.build({ // first time
      username: profile.username,
      givenName: profile.name.givenName,
      familyName: profile.name.familyName
    }).save();
  }).then(function(user) {
    return Auth.build({
      provider: 'facebook',
      providerId: profile.id,
      accessToken: accessToken
    }).return(user);
  });
}