Node.js 교과서에 로그인 기능은 있지만 로그아웃 기능이없어서 공부하며 쓴 글....
passport doc에 있는 로그아웃을 참고해 만들더라도 카카오톡 로그아웃은 되지않는다. 로그아웃 후에 카카오톡 로그인을 누르는 경우 id와 비밀번호를 입력하지 않았는데도 자동 로그인이 되어버린다.. 이걸 막기위해서 열심히 찾아봄 ㅎㅎ;
준비물
axios와 passport-kakao를 사용해 로그인기능 구현
카카오 개발자 사이트
https://developers.kakao.com/docs/latest/ko/kakaologin/rest-api#unlink
카카오 로그아웃 구현하기
😂 어떻게 하지?
로그아웃을 구현하기 위해서 카카오 디벨로퍼 사이트를 참고.
내가 원한 것 => 예시코드
거기 있던 것..
사실 이걸 딱 보는 순간 뭘해야할지 정말 감이 안잡혔다..액세스 토큰을 저기로 리퀘스트 보내라는 거 같긴한데...
액세스 토큰은 그럼 어디에 있는가..?
🍕 ACCESS_TOKEN
카카오 개발자 페이지를 보면, 토큰은 로그인에 성공하면 발급받는다.
passport-kakao를 사용할 때, 로그인을 결정 짓는 부분은 kakao전략을 만드는 곳이다.
로그아웃 요청을 보내기 위해서 토큰 정보가 필요하다.
따라서 카카오 전략을 만드는 과정에서 profile 데이터 뿐만아니라 accesToken 데이터도 콜백함수에 넘겨줘야한다!
전략을 수행해서 얻은 db에서 가져온 유저 데이터 exUser와 accessToken을 같이 콜백함수에 넘겼다.
🍳 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라면 카카오 로그아웃 방식을 따르고, 아니면 로컬 방식을 따르도록 로그아웃 라우터에서 처리해줄 생각.
'공부 > 노드' 카테고리의 다른 글
[passport] 이해하기 (1) | 2021.07.07 |
---|---|
[express] req.body가 undefined인 경우 (2) | 2021.07.04 |
[express] - 미들웨어 뽀개기 (0) | 2021.07.03 |
[passport-kakao] 카카오 로그인 API (0) | 2021.07.01 |
[error] Uncaught TypeError: Illegal invocation (1) | 2021.06.30 |
댓글