본문 바로가기
공부/노드

[passport-kakao] 로그아웃 구현하기

by 야옹아옹 2021. 7. 7.

Node.js 교과서에 로그인 기능은 있지만 로그아웃 기능이없어서 공부하며 쓴 글....

passport doc에 있는 로그아웃을 참고해 만들더라도 카카오톡 로그아웃은 되지않는다. 로그아웃 후에 카카오톡 로그인을 누르는 경우 id와 비밀번호를 입력하지 않았는데도 자동 로그인이 되어버린다.. 이걸 막기위해서 열심히 찾아봄 ㅎㅎ;


준비물

axios와 passport-kakao를 사용해 로그인기능 구현

 

카카오 개발자 사이트

https://developers.kakao.com/docs/latest/ko/kakaologin/rest-api#unlink

 

Kakao Developers

카카오 API를 활용하여 다양한 어플리케이션을 개발해보세요. 카카오 로그인, 메시지 보내기, 친구 API, 인공지능 API 등을 제공합니다.

developers.kakao.com


카카오 로그아웃 구현하기

😂 어떻게 하지?

 

로그아웃을 구현하기 위해서 카카오 디벨로퍼 사이트를 참고.

내가 원한 것 => 예시코드

 

거기 있던 것..

사실 이걸 딱 보는 순간 뭘해야할지 정말 감이 안잡혔다..액세스 토큰을 저기로 리퀘스트 보내라는 거 같긴한데...

액세스 토큰은 그럼 어디에 있는가..?

 

🍕 ACCESS_TOKEN

카카오 개발자 페이지를 보면, 토큰은 로그인에 성공하면 발급받는다.

passport-kakao를 사용할 때, 로그인을 결정 짓는 부분은 kakao전략을 만드는 곳이다.

책 예제에서는 profile만 사용하지만 accessToken과 refreshToken도 받아온다.

로그아웃 요청을 보내기 위해서 토큰 정보가 필요하다.

따라서 카카오 전략을 만드는 과정에서 profile 데이터 뿐만아니라 accesToken 데이터도 콜백함수에 넘겨줘야한다!

 

전략을 수행해서 얻은 db에서 가져온 유저 데이터 exUseraccessToken을 같이 콜백함수에 넘겼다.

그래서 같이 넘겨줬다.

 

🍳 serializeUser를 수정하기

  passport.serializeUser((data, done) => {
    console.log('시리얼라이즈 유저', data); // user는 tokenUser다.
    // 로그인 시, 사용자 데이터를 세션에 저장하는데
    done(null, {id : data.user.id, accessToken : data.accessToken});
  });

넘겨주는 data가 { user: exUser, accessToken : accessToken } 형식으로 바뀌었으니

serializeUser도 세션에 저장하는 id값 구조를 변경해줘야한다.

!토큰도 함께 세션에 저장해야한다!

deserializeUser는 세션에 저장된 id로 데이터베이스에서 id값이 일치하는 값을 가져오는 것이기 때문에 따로 세션에 계속 저장해둔다.

 

🧇 deserializeUser를 수정하기

  passport.deserializeUser((user, done) => {
    // user = {id : data.user.id, accessToken : data.accessToken}
    console.log('디시리얼라이즈 유저', user);
    User.findOne({ where: { id:user.id } })
      .then((result) => { // db에서 가져온 유저데이터 결과 result
        // console.log('디시리얼라이즈에서 찍히는 유저',user);
        const tokenUser = { user: result, accessToken : user.accessToken}; 
        done(null, tokenUser); // req.user 에 저장된다.
      }) // 조회한 정보를 req.user에 저장한다.
      .catch((error) => done(error));
  });

deserializeUser의 매개변수 user는 serializeUser가 보내는 데이터다.

즉, serializeUser메서드 안에있는 코드, data(null, 여기있는 걸 보낸다 )

user = { id: 아이디값, accessToken: 토큰값 }

이제 id 값으로 db에서 사용자 데이터 정보를 조회해 가져오고,

세션에 토큰과 사용자 데이터 정보를 함께 저장하면된다.

 

🍟 로그아웃 라우터 만들기

이제 토큰도 구했으니 토큰을 담아서 로그아웃 리퀘스트를 보내면된다!

이때 통신을 위해서 axios를 사용했다.

 

// 카카오 로그아웃
// auth//kakao/logout
router.get('/kakao/logout', async (req,res)=>{
  // https://kapi.kakao/com/v1/user/logout
  try {
    const ACCESS_TOKEN = res.locals.user.accessToken;
    let logout = await axios({
      method:'post',
      url:'https://kapi.kakao.com/v1/user/unlink',
      headers:{
        'Authorization': `Bearer ${ACCESS_TOKEN}`
      }
    });
  } catch (error) {
    console.error(error);
    res.json(error);
  }
  // 세션 정리
  req.logout();
  req.session.destroy();
  
  res.redirect('/');
})

나는 유저 정보를 res.locals.user에 저장해 놓기때문에 저기서 토큰을 가져왔다.

토큰을 담아서 연결끊는 요청을 보낸다.

그리고 세션도 정리해준다.


결과

로그인 - 로그아웃 후, 다시 로그인을 하면 이제 물어본다.


후기

doc를 읽고 만들어보려고 최대한 노력하고있는데, 잘 해결되서 기쁘다.

카카오 로그아웃 버튼 말고 로그아웃 버튼을 하나로 통일해야하는데.. 주말에 도전해볼 생각이다.

생각중인건 db에 어떤 계정으로 로그인했는지 provider라는 속성(컬럼)으로 저장하는데, 그 값이 kakao라면 카카오 로그아웃 방식을 따르고, 아니면 로컬 방식을 따르도록 로그아웃 라우터에서 처리해줄 생각.

댓글