이 블로그는 광고 클릭 수익으로 운영됩니다!
괜찮으시다면 광고 차단을 풀어주세요 ㅠㅠ

게시글

강좌11 - NodeJS - 일 년 전 등록 / 3달 전 수정

Passport로 Facebook 로그인

조회수:
0
이 블로그는 광고 클릭 수익으로 운영됩니다!
괜찮으시다면 광고 차단을 풀어주세요 ㅠㅠ
이 블로그는 광고 클릭 수익으로 운영됩니다!
괜찮으시다면 광고 차단을 풀어주세요 ㅠㅠ

안녕하세요. 이번 시간에는 passport를 사용해 facebook 아이디로 로그인을 구현해보겠습니다. 이것을 응용하면 google이나 twitter, kakao 등 passport를 지원하는 SNS 아이디로 로그인할 수 있습니다.

우선 passport-facebook을 설치합니다.

npm install --save passport-facebook

설치가 완료되었으면 페이스북에 로그인 요청을 보낼 라우터를 추가합니다.

route.js

... // 이전 시간 코드에서 계속
router.get('/auth/facebook', passport.authenticate('facebook', {
  authType: 'rerequest', scope: ['public_profile', 'email']
}));
router.get('/auth/facebook/callback', passport.authenticate('facebook', { failureRedirect: '/' }), function(req, res) {
  res.redirect('/');
});

전 시간과 달리 router에 두 개를 추가했습니다. /auth/facebook은 로그인 요청을 할 링크입니다. 이 링크를 html로 만들고 클릭하면 passport를 통해 페이스북으로 로그인 요청이 전송됩니다. authenticate 메소드 뒤의 facebook은 사용할 전략의 이름을 적어주면 됩니다.

authType: 'rerequest'는 매번 로그인 할 때마다 뒤의 public_profile과 email을 달라고 요청하는 겁니다. 이것을 해둬야 실수로 사용자가 요청을 거절했을 때 다음 로그인 시 다시 얻어올 수 있습니다. 뒤에 scope는 페이스북에 사용자에 대한 정보로 무엇을 요청할 지 정하는 부분입니다. 친구목록이나 좋아요한 페이지 등등 다양한 정보를 얻어올 수 있습니다.

/auth/facebook/callback은 페이스북이 검증을 마치고 난 결과를 전송해주는 주소입니다. 여기로 전송한 정보를 처리하는 코드를 만들어보죠. 지난 시간 만들었던 passport.js의 LocalStrategy 아래에 다음 코드를 추가해줍니다.

passport.js

const passport = require('passport');
const LocalStrategy = require('passport-local').Strategy;
const FacebookStrategy = require('passport-facebook').Strategy; // 이 부분 추가
const Users = require('./user');

module.exports = () => {
  ... // 이전 시간 코드에서 계속
  passport.use(new FacebookStrategy({
    clientID: '페이스북 클라이언트 아이디',
    clientSecret: '페이스북 클라이언트 시크릿',
    callbackURL: '홈페이지주소/auth/facebook/callback',
    passReqToCallback: true,
  }, (req, accessToken, refreshToken, profile, done) => {
    User.findOne({ id: profile.id }, (err, user) => {
      if (user) {
        return done(err, user);
      } // 회원 정보가 있으면 로그인
      const newUser = new User({ // 없으면 회원 생성
        id: profile.id
      });
      newUser.save((user) => {
        return done(null, user); // 새로운 회원 생성 후 로그인
      });
    });
  });
};

슬슬 코드가 콜백 지옥으로 빠져들어가고 있네요. 찬찬히 살펴봅시다. 일단 passport-facebook도 Strategy를 사용합니다. 전략이라고 했죠? 페이스북 로그인은 페이스북 서버에서 clientID, clientSecret, callbackURL을 검사합니다. 이 부분은 나중에 무엇을 넣어야하는지 알려드릴게요.

passReqToCallback 옵션은 지난 시간에 설명드렸습니다. 뒤의 콜백 함수에 req 매개변수를 추가해주죠.

accessToken, refreshToken은 페이스북 API를 사용할 수 있는 토큰을 전달해줍니다. 만약 페이스북이 토큰 내놔라! 라고 하면 이 토큰을 주면 됩니다. profile은 간단한 페이스북 사용자의 정보를 알려줍니다. 별로 알려주는 게 많이 없어서 추가적인 정보를 원한다면 추가 API를 호출해야 합니다.

이제 전략 부분을 설명하겠습니다. 일단 profile.id로 이미 우리 사이트의 회원인가를 조회해봅니다. 만약 우리 사이트에 이미 가입되어 있으면 done(err, user)로 바로 로그인합니다. 회원이 아니라면 새로 회원가입하는 거죠.

거의 다 되었는데 이제 clientIDclientSecret을 넣어야합니다. 이것이 있어야 페이스북에서 보내준 결과가 올바른 사이트에 전달되었는지 확인할 수 있거든요. 이것을 얻으려면 페이스북 개발자 홈페이지에 접속해야 합니다.

로그인 후 상단 오른쪽 내 앱 -> 새 앱 추가 -> 웹사이트를 누르세요. 원하는 앱 이름을 적고 Create New Facebook App ID를 누르면 됩니다.

undefined

저는 test로 앱을 만들었는 데 이름은 원하는 걸로 바꾸세요. 정보를 알맞게 적고 앱 ID 만들기를 누릅니다. 사이트 주소도 넣어줍니다.

undefined

이제 오른쪽 위 내 앱 -> test에 가면 clientID와 clientSecret을 확인할 수 있습니다.

undefined

마지막으로 좌측 메뉴에서 제품 -> 제품 추가를 클릭하여 Facebook 로그인 제품을 활성화합니다. 웹을 클릭한 후 사이트 주소를 입력하면 됩니다. 나머지 것들은 건너뛰어도 됩니다.

좌측 메뉴에 Facebook 로그인이 추가되었는지를 확인합니다.

undefined

위의 코드를 활용해서 다른 SNS 로그인도 구현해보세요. 저는 현재 페이스북, 구글+, 트위터, 카카오, 네이버 이렇게 다섯 개를 사용중입니다. 다음 시간에는 socket.io에 대해 알아보겠습니다.

투표로 게시글에 관해 피드백을 해주시면 많은 도움이 됩니다. 오류가 있다면 어떤 부분에 오류가 있는지도 알려주세요! 잘못된 정보가 퍼져나가지 않도록 도와주세요.
Copyright © 2016- 무단 전재 및 재배포 금지

댓글

4개의 댓글이 있습니다.
3달 전
" 클라이언트 로딩 후 직접 서버 세션 조회를 해야 합니다.
친절하고 빠른 답변, 감사합니다 며칠 생각 안나던 문제가 해결되듯 답답함이 풀리네요!

혹시 저와 같이 Vue-cli나 React에서 고민을 하시는 분들이 있을까봐 간단하게 남겨둡니다
- vue는 https://www.npmjs.com/package/vue-session 해당 모듈 사용해서 session키를 저장하면 서버사이드 렌더링 없어도 가능할듯 보입니다.
3달 전
안녕하세요 ㅎㅎ 항상 글 잘보고있습니다 이번에도 좋은글 써주셔서 감사합니다
다름이 아니라 passport를 vue프로젝트와 연동 시키려고 하는데요 프로그래밍 기획과정에서 약간의 질문이 생겨서 이렇게 글을 남기게 되었습니다.

passport는 세션스토리지 형식으로 저장하는걸로 알고있습니다 그래서 질문이 생겼는데요
Vue의 컴포넌트 형식의 개발방식이나 ReactJs의 jsx의 클래스를 사용한 앱과같은 웹개발..을 보면서 느끼는건데 여기서 passport를 붙이려면 어떤식으로 생각하면 좋을까요?

Vue는 -cli를 사용해서 빌드를 하면 빌드 파일이 생기고 정적으로 파일을 제공하는 것으로 알고있습니다. 그래서 서버와의 통신을 htttp.get or http.Post 형식으로 주고받는데요 이 과정 만으로도 사용자의 피씨의 정보를 받아 세션화 시켜서 저장이 가능 한지가 궁금하네요

전통적인 웹 개발방식에서 벗어나 새로운 방식을 사용하고자 하는데 기존에 생각하던 방식이랑 전혀다르다보니 이렇게 질문하게 되었습니다.
3달 전
서버 사이드 렌더링을 사용해야 합니다. 제 블로그도 리액트인데 세션이 유지되는 이유가 서버사이드렌더링을 하여 처음 렌더링할때부터 세션 정보를 삽입하기 때문입니다. 만약 서버사이드렌더링이 불가능하다면 클라이언트 로딩 후 직접 서버 세션 조회를 해야 합니다.
5달 전
중간에 passport.js에 25line })); 인듯 한데요~
5달 전
감사합니다 ㅎㅎ
8달 전
게시물이 구글을 다 뒤진 것보다 더 도움이 되었습니다! 그런데 몇 가지만 질문 드리고 싶은데요~ 맨 처음에 클라이언트가 서버에게 /auth/facebook으로 요청을 보낼 때 어떤 정보를 보내는 건가요?? 그리구 마지막에 done이 호출되는데, 이제 로그인이 끝나고 클라이언트가 서버에게 요청을 할 때는 facebook access_token이 전송되는건가요?? 워낙 자료 찾기가 어려워서 지식이 부족하네요 ㅜㅜ 죄송합니다
8달 전
/auth/facebook으로 보내는 건 서버에게 passport 요청을 수행하라고 지시하는 것이고요. 서버에서 한 번 더 facebook 인증 서버로 요청을 합니다. facebook 인증 서버에서 프로필과 액세스 토큰을 돌려주면 지정해둔 passport 전략이 실행되고요. DB에 저장 후 done이 호출되면 req.user에 profile이 저장되는 겁니다. access_token은 여기서 아무 역할이 없습니다.