2013-06-06 1 views
0

Express와 함께 Passport 노드 모듈을 사용하여 사용자가 Facebook, Twitter 및 Google을 통해 로그인 할 수있게합니다. 지금까지 Facebook과 Twitter를 설정했고 사용자가 성공적으로 로그인 할 수 있지만 사용자가 이미 계정을 만들었을 때이를 인식하도록 만들었지 만 매번 새로운 사용자를 만듭니다. 나는 사용자 프로필과 연결된 각 이메일을 통해 루프를 가지고 있고 해당 사용자가 우리의 데이터베이스에 이미 있는지 여부를 확인 processProfile에서Facebook OAuth는 Passport 및 Express를 사용하여 매번 새로운 사용자를 생성합니다.

passport.use(new FacebookStrategy({ 
     clientID: '********************', 
     clientSecret: '***********************', 
     callbackURL: "http://www.wundertutor.com:3000/auth/facebook/callback" 
    }, function(accessToken, refreshToken, profile, done) { 
     processProfile(profile, function(err, user) { 
      if (err) throw err; 
      done(null, user); 
     }); 
    })); 
function processProfile(profile, callback) { 
     if (profile.emails) { 
      profile.emails.forEach(function(email) { 
       findUserByEmail(email.value, function(err, user) { 
        if (user) { 
         return callback(null, user); 
        } 
       }); 
      }); 
      var newUser = { 
       id: profile.id, 
       firstName: profile.name.givenName, 
       lastName: profile.name.familyName, 
       email: profile.emails[0].value 
      }; 
      user.create(newUser, profile.provider, function(err, user) { 
       if (err) throw err; 
       return callback(null, user); 
      }); 
     } 
    } 


    function findUserByID(id, callback) { 
     pool.getConnection(function(err, connection) { 
      var query = connection.query("SELECT * FROM users WHERE id = ?", id, function(err, rows) { 
       connection.end(); 
       var user; 
       if (rows.length == 1) { 
        user = { 
         id: rows[0].id, 
         role: rows[0].role, 
         firstName: rows[0].firstName, 
         lastName: rows[0].lastName, 
         email: rows[0].email 
        }; 
       } 
       return callback(null, user); 
      }); 
     }); 
    } 


    function findUserByEmail(email, callback) { 
     if (email) { 
      pool.getConnection(function(err, connection) { 
       if (err) throw err; 
       var query = connection.query('SELECT * FROM users WHERE email = ?', email, function(err, rows) { 
        connection.end(); 
        if (err) throw err; 
        if (rows.length == 1) { 
         console.log("C"); 
         return callback(null, rows[0]); 
        } else { 
         return callback(null, null); 
        } 
       }); 
      }); 
     } else { 
      return callback(null, null); 
     } 
    } 

    passport.serializeUser(function(user, done) { 
     done(null, user.id); 
    }); 

    passport.deserializeUser(function(id, done) { 
     findUserByID(id, function(err, user) { 
      done(null, user); 
     }); 
    }); 

: 여기에 내가 사용하고있는 코드입니다. 그럴 경우 해당 사용자의 정보를 가져 와서 'done'콜백에 전달하여 직렬화하고 사용자를 로그인합니다. 이상한 일은 이미 데이터베이스에있는 사용자가 로그인하면 이 코드 부분은 일련의 console.logs에 의해 성공적으로 사용자를 반환하지만 어떤 이유로 로그인 할 때마다 계속 데이터베이스에 새 사용자를 만듭니다.

또한 사이드 노트, 정상적으로 (사용자 이름과 패스워드를 통해) 로그인 할 때 학습 페이지 '/ learn'으로 리디렉션됩니다. 그러나 페이스 북을 통해 로그인 할 때 이후에 몇 가지 추가 정보가있는 학습 페이지로 리디렉션됩니다 '/ 배우기 # = '입니다. 어떤 아이디어?

답변

1

이런 식으로 processProfile 기능을 다시 작성하십시오 :

function processProfile(profile, callback) { 
     var result; 
     if (profile.emails) { 
      profile.emails.forEach(function(email) { 
       findUserByEmail(email.value, function(err, user) { 
        if (user) { 
         result = user; 
        } 
       }); 
      }); 
      if(!user) { 
       var newUser = { 
        id: profile.id, 
        firstName: profile.name.givenName, 
        lastName: profile.name.familyName, 
        email: profile.emails[0].value 
       }; 
       user.create(newUser, profile.provider, function(err, user) { 
        if (err) throw err; 
        result = user; 
        callback(null, result); 
       }); 
      } else { 
       callback(null, result); 
      } 
     } 
    } 
관련 문제