2014-11-09 3 views
1

나는 node.js의 초보자이며, 후계자, Bluebird 약속 및 FB 인증을 받았습니다.node.js 코드 개선 (sequelize, promises 및 passport)

FB 인증 사용자에게 인증 세부 정보를 제공하고 싶습니다.

내 모델에서는 한 사용자가 여러 인증 (브라우저 용, 모바일 용 등)을 동시에 수행 할 수 있습니다. 이러한 인증을 처리해야하므로 다음 관계가 있습니다.

User.hasMany (Auth); Auth.belongsTo (사용자);

나는이 코드를 작성했지만 여전히 똑똑한 솔루션을 찾고 있습니다.

주요 목표는 인증 정보를 사용자에게 추가하는 것입니다. 따라서 인증 정보를 배포하기 전에 영구 사용자를 찾습니다.

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"} 

이 user.addAuth (인증)의 인증 객체를 반환 할 것을 처리 할 이상한 것이 었습니다. 그 다음에 메서드에서 auth 대신 user 개체를받을 것으로 예상했습니다. 해결 방법으로 주 함수 범위에서 끔찍한 thatUser 변수를 사용했습니다. 더 똑똑한 방법이 있습니까?

로그에 "USER IS # 3 :"추적은 인증 개체가없는 사용자를 보여줍니다. 왜? 당신이 약속을 사용하는 경우

모든 수정 또는 개선

감사

답변

1

을 wellcomed 될 것이다 - 당신은 done 콜백을 제거 할 수 있습니다 - 당신은 단순히 약속을 반환 할 수 있습니다. 완성 된 콜백을 원한다면 명시 적으로 호출하는 대신 .nodeify을 호출 할 수 있습니다. 반환 약속에는 처리되지 않은 거부 추적과 같은 다른 이점이 있습니다.

당신은 대신 명시 적 폐쇄 범위의 집계 방법을 사용할 수 있습니다 : 나는 모든 console.log의 드롭 할 수있어 경우,

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

지금이 훨씬 짧은 가져옵니다

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