Juni_Dev_log

Federation authentication(타사인증) ④ 본문

Theorem (정리)/node.js

Federation authentication(타사인증) ④

Juni_K 2020. 6. 17. 09:00

페이스북 인증처리를 계속해서 진행해보도록 하자.

 

새로운 페이스북 전략을 작성하는 코드에서, 페이스북 정보를 가져오는 코드를 작성해보자.

 

function(accessToken, refreshToken, profile, done) {
    // console.log 를 통해서 profile에 무엇이 들어가있는지 확인해보자.
    console.log(profile);
    // 페이스북 상에서의 id 값을 가져와야한다. (굉장히 중요한 요소)
    // 페이스북으로 인증한 사용자이기 때문에, facebook 과 식별값인 profile.id 를 가져온다.
    var authId = 'facebook:' + profile.id;
    // user 객체로 넣을 객체 배열을 정의한다.
    // 사용자가 이미 존재하다면, 추가할 필요가 없기 때문에 존재한지 먼저 파악해야한다.
    for (var i = 0; i < users.length; i++) {
      var user = users[i];
      // user 객체에 authid 값과 현재 로그인할때의 authId 과 같다면,
      // 이미 존재한 사용자이다.

      if (user.authId === authId) {
        // 이미 user 객체에 사용자가 있을 때
        // done 의 두 번째 인자로 user가 들어가면, 이미 존재한 유저라는 것을 의미한다.
        return done(null, user);
      }
    }
    // user 객체에 사용자가 없다면
    var newuser = {
      'authId': authId,
      // local과 facebook 둘 다 displayName 이 똑같은 요소로 들어가고있다.
      'displayName': profile.displayName
      //username 으로 계속해서 식별을 했는데, 이제는 authId를 통해서 식별을 해야한다.
      //그렇게 되면, 어떤 값을 식별값으로 해야할지 정해야하는데, 우리는 authId 로 통일한다.
    };
    users.push(newuser);
    // 새로운 사용자를 보내서, serializeUser 를 실행한다.
    done(null, newuser);
  }

 

함수를 통해서 전달받은 정보를 담는 인자 profile 을 찍어보면 해당 정보를 담고있다는 것을 볼 수 있다.

 

(console.log(profile))

 

{
  id: '3013299475421902',
  username: undefined,
  displayName: '???',
  name: {
    familyName: undefined,
    givenName: undefined,
    middleName: undefined
  },
  gender: undefined,
  profileUrl: undefined,
  provider: 'facebook',
  _raw: '{"name":"\\uae40\\uc9c0\\ud6c8","id":"3013299475421902"}',
  _json: { name: '???', id: '3013299475421902' }
}
// name 은 개인정보 보호를 위해서 ??? 로 대체합니다.

 

해당 정보에서 가져와야할 정보는 id displayName 이다.

페이스북에서 가져온 id 를 새로운 변수에 담고, for 문을 통해서 users 배열에 해당 사용자의 정보가 있는지 없는지를 파악한다.

 

만약, 사용자의 정보가 있다면,

return done(null, user);

을 통해서 serializeUser 로 해당 유저의 정보를 담은 객체를 보내고,

 

만약, 사용자의 정보가 없다면, newuser 변수에 새롭게 저장할 형태를 만들고, (authIddisplayName 을 넣어서!!) 사용자의 정보를 저장하는 users 배열에 넣고, serializeUsernewuser 객체를 보낸다.

 

여기서 중요한 점은, 기존에는 user.username 을 식별값으로 정했다면, 이제는 authId 를 식별값으로 정했기 때문에, user.username 을 활용해서 식별하는 작업을 수정해줘야한다.

 

그렇기 때문에, 기존의 정보에 local 에 저장되어있는 사용자의 정보에 authId 를 추가한다.

 

var users = [{
  // 기존의 local 방식으로 가입한 사용자
  // authId 로 식별을 해야하기 때문에, authId를 추가한다.
  authId: 'local:egoing',
  username: 'egoing',
  password: 'mTi+/qIi9s5ZFRPDxJLY8yAhlLnWTgYZNXfXlQ32e1u/hZePhlq41NkRfffEV+T92TGTlfxEitFZ98QhzofzFHLneWMWiEekxHD1qMrTH1CWY01NbngaAfgfveJPRivhLxLD1iJajwGmYAXhr69VrN2CWkVD+aS1wKbZd94bcaE=',
  salt: 'O0iC9xqMBUVl3BdO50+JWkpvVcA5g2VNaYTR5Hc45g+/iXy4PzcCI7GJN5h5r3aLxIhgMN8HSh0DhyqwAp8lLw==',
  displayName: 'Egoing'
}];

 

회원가입을 할 때, 역시 authId 를 추가한다.

 

app.post('/auth/register', function(req, res) {
  hasher({
    password: req.body.password
  }, function(err, pass, salt, hash) {
    var user = {
      // authId로 식별값을 변경했기 때문에, authId 를 추가한다.
      authId: 'local:' + req.body.username,
      username: req.body.username,
      password: hash,
      salt: salt,
      displayName: req.body.displayName
    };
    users.push(user);
    req.login(user, function(err) {
      req.session.save(function() {
        res.redirect('/welcome');
      });
    });
  });
});

 

serializeUserdeserializeUser 역시 식별값을 authId 로 변경한다.

 

passport.serializeUser(function(user, done) {
  console.log('serializeUser', user);
  // 주는 값으로 user.authId로 변경. (식별값을 변경했기 때문에)
  done(null, user.authId);
});

// 로그인을 해놓고 꺼버리면, 세션을 파일형태로 저장되어있는데,파일 형태로 저장되어있는 세션을 계속해서 가져오려고하는데
// users 가 없어서 계속 반복되는 문제가 발생한다.
// 이럴 떄는 세션을 지워버리면 가능하다.
passport.deserializeUser(function(id, done) {
  console.log('deserializeUser', id);
  for (var i = 0; i < users.length; i++) {
    var user = users[i];
    // 식별값을 user.authId로 변경.
    if (user.authId === id) {
      return done(null, user);
    }
  }
  done('There is no user.');
});
Comments