★ SPA_BLOG_LV3 development!
- 기존에 만들어 놓은 refreshToken도 괜찮지만 결국 이 Tokens의 DB에는 하나의 데이터만 저장이 되기에 DB로서의 효율성은 떨어지지 않나? 라고 같이 작업하시는 상훈님이 의견을 남겨주셨음
- 다른 해결 방법? 그러면 DB도 좀 더 유용하게 사용이 가능하면서 refreshToken을 사용할 수 있는 방법을 고안하다가 찾은 방법이 흔히 웹사이트에서 볼 수 있는 사용자 계정 전환 기능으로 development 하기로 함.
☆ 알고리즘 구상
- 1) 사용자가 처음 로그인을 하게 된다면 accessToken과 refreshToken을 같이 발급함, 만료기한은 이전과 동일, 이미 refreshToken을 발급받은 사용자가 재 로그인을 하게 된다면 해당 토큰을 검증 해 검증이 완료되면 새 accessToken만 발급을 하고 refreshToken은 그대로 사용을 하되 DB에 저장된 해당 userId의 토큰은 한 번 지웠다가 다시 생성함( why? 여러 사용자가 들어와 있는 구조 상 현재 로그인 중이던 사용자의 토큰이 만료되거나 로그아웃을 했을 때 남아 있는 사용자 중에 어떤 사용자가 로그인 상태를 유지할 것이냐? 라고 생각을 했었을 때, 그럼 가장 마지막으로 로그인을 했던 사용자 즉, createdAt이 가장 최신인 사용자(DESC했을 때 제일 위에 위치)를 로그인 상태로 자동으로 변경되도록 하자! 라고 생각이 들었기 때문에 로그인 순서를 정하기 위해서 지웠다가 다시 생성하는 방법을 차용)
- 2) 로그아웃 기능을 추가해서 userId를 params로 받아 해당 userId의 토큰 값만을 DB에서 삭제하고 쿠키도 삭제를 해서 로그아웃이 되도록 설정
☆ 문제점 ? 기존에 저장된 쿠키를 삭제하게 된다면 지금 현재 로그인 된 유저의 쿠키 값을 지워버린다는 것으로 만약 내가 로그인된 유저가 아닌 다른 즉 refreshToken에만 저장이 되어 있는 사용자를 로그아웃 하고 싶을 경우에는 원치 않는 결과가 발생할 수 있지 않을 까 생각(ex) 현재 user1로 로그인이 되어있고 Tokens에는 uesr1, 2, 3 세 개의 토큰이 저장이 되어 있을 때, user2를 로그아웃 한다고 하면 uer1의 쿠키 값까지 삭제가 됨)
=> 해결 : 어차피 기존의 쿠키 값이 삭제가 되어 있더라도 로그인 되어 있는 유저 즉 user1의 정보는 DB에 저장이 되어 있고 accessToken이 없을 때 refreshToken을 검증해서 새로 발급 받으면 되기에 큰 문제가 되지 않아 보임!
- 3) 사용자 계정 전환 기능 추가 : userId를 params로 받아 해당 userId의 토큰이 DB에 존재하고 이 토큰의 검증이 통과가 된다면 이 토큰을 현재 로그인 된 유저의 정보로 바꾸기 위해 DB에서 삭제하고 재생성, accessToken을 새로 발급
☆ 코드
1) 로그인
=> 사용자 계정 전환 API도 로그인과 유사한 로직이기에 계정 전환 코드는 생략
2) 로그아웃
=> 로그인이 되어 있는 정보인지 확인하고 DB에 저장된 정보라면 삭제하고 쿠키도 삭제(현재 로그인한 유저일 가능성이 제일 높으니 삭제)
☆ 해당 코드를 정상 작동시키기 위한 auth-middleware.js 수정
- 원초적으로 로그인이 필요한 기능의 작업을 수행하기 위해 쿠키에 담긴 유저 정보(로그인 된 사용자)가 있어야 함.
- 그렇다면 우리는 accessToken의 검증만 완료가 된다면 해당 작업을 사용이 가능 하기 때문에 accessToken의 상태가 제일 중요!(refreshToken은 accessToken이 만료되거나 삭제 되어 없을 때를 위해 사용하기 위한 토큰id)
- 알고리즘 구상 1) accessToken과 refreshToken이 둘 다 없다면 토큰이 아예 없는 경우니까 로그인을 하도록 설정
- 2) accessToken이 삭제(만료x)된 경우 refreshToken을 검증 해 검증이 완료되면 해당 userId의 accessToken을 생성
- 3) accessToken과 refreshToken이 둘다 있을 때 accessToken을 검증해 검증이 되면 바로 해당 값을 로그인된 유저의 정보로 사용하고 만약 만료가 되었다면 그 다음에 refreshToken을 검증을 해서 이 refreshToken이 검증이 되면 새로운 accessToken을 발급하고 만료가 된 refreshToken이라면 DB에서 해당 토큰을 삭제하고 재로그인 하라는 오류 반환
- why refreshToken 만료시 삭제 ? 해당 토큰이 만료가 되어 있다면 자연스럽게 그 다음으로 로그인을 한 사용자가 로그인이 되는 상황으로 바꾸기 위해서 ex) 만약 여러 사용자가 로그인 된 상황에서 내가 로그아웃을 하거나 쿠키가 삭제가 되어서 만료된 refreshToken을 검증해야 하는 상황일 때, 로그아웃하거나 잘못된 토큰을 가진 사용자의 다음 사용자의 정보로 넘어가기 위해서는 삭제를 해줘야 함(로그인 된 유저의 정보를 가져올 때 생성된 역순의 제일 처음 것만 가져와 해당 유저를 현재 로그인 된 유저로 인식하도록 구현했기 때문) - 삭제해 주지 않으면 다음으로 넘어가지 않음
☆ 코드
- 구상 1, 2는 이전에 작성한 코드와 일치하기에 생략
case 3)
=> 둘 다 있다면 accessToken을 검증해서 검증이 되면 해당 토큰이 현재 로그인 된 유저의 정보
case 4)
=> accessToken이 만료가 되었다면 refreshToken을 검증 해 검증이 되면 새 accessToken을 생성
case 5) accessToken 과 refreshToken 둘다 만료
=> 둘 다 만료가 되었다면 해당 tokenId를 DB에서 삭제하고 만료 되었으니 다시 로그인 해달라고 메시지 반환
☆최종 완료된 코드의 DB의 ERD

※ 간단하게 추가해야 하지라고 생각해서 그렇게 길게 걸리지 않을 꺼같다 생각했었는데 상훈님과 서로 구현하려 했던 방식이 다르기도 했고 체크해야 할 상황이 구현하면서 많이 생겨서 좀 오래 걸렸다. 다음에 진행을 할 때는 필요한 요구사항이나 기능을 확실하게 정리하고 development를 하면 될 거 같다!
'JS > Node.js' 카테고리의 다른 글
| TIL(2023.06.27) (0) | 2023.06.29 |
|---|---|
| Node.js 숙련 (0) | 2023.06.25 |
| TIL(23.06.22) .env 설정 / refreshToken 생성 (0) | 2023.06.24 |
| TIL(23.06.21) - 게시글 / 댓글 RestAPI 구현 (0) | 2023.06.22 |
| Node.js 입문 (0) | 2023.06.20 |