미사일 마켓 :: 로그인, 회원가입

전은찬·2023년 5월 7일
0
post-thumbnail


로그인과 회원가입을 구현했다.

회원가입은 어려울 건 없다.
입력해야할 값을 입력하고 Mutation으로 백 서버에 보내주면 되는 거라 다른 Mutation과 똑같다고 보면 된다.

그러나 로그인은 거의 모든 웹사이트에서 구현되어있지만 제일 어렵다고해도 과언이 아니다.

우선 브라우저에 남긴 데이터를 저장하는 방법에는 무엇들이 있을까.

로컬스토리지, 세션스토리지, 쿠키가 대표적이다.

각각의 특징을 말해보자면

로컬스토리지는 브라우저를 종료한 후에 다시 켜도 정보가 남아있고,
세션스토리지는 브라우저를 종료하면 정보가 사라진다.
쿠키는 생명주기로 만료 날짜를 입력하면 그 날짜까지 유지되고, 만료 날짜를 설정하지 않으면 브라우저 종료시 사라진다.

이러한 특징들을 가지고 있는데 로컬스토리지나 세션스토리지는 주로 쇼핑몰 웹에서 장바구니, 최근 본 상품 등에 쓰인다.

우리가 어떤 웹사이트에서 로그인했을 때 브라우저를 닫아도 다시 키면 로그인이 되어있는 경우가 있다.
로그인 정보를 쿠키에 저장하고 백 서버에서 설정한 만료 날짜까지 정보가 살아있기 때문이다.

로그인 방식 채택 관련 글은 이전의 작성한 글을 참고해주세요!
👉🏻로그인 방식 & 로그인의 역사👈🏻

사용자가 가입된 계정으로 로그인하면 AccessToken(JWT토큰)을 받아 온다.
이 AccessToken이 기한이 만료되고 로그인 권한분기처리가 되어있는 페이지에 접근하려고하면 백엔드에서는 에러를 보내준다.
그렇기 때문에 AccessToken 기한이 만료되면 새로운 AccessToken을 받아와야하는데 이를 RefreshToken이라고 칭한다.

대체로 AccessToken은 비교적 짧은 만료기한을 가지고 있고,
RefreshToken은 그에 비해 좀 더 긴 만료기한을 가지고있다.

이 RefreshToken은 보안에 약한 로컬/세션 스토리지가 아닌 쿠키에 담는다.
쿠키에 저장한다고 무조건 안전한 것은 아니지만 https 통신에서만 쿠키를 받아올 수 있어 보다 안전한 것이다.

과정을 설명하면 이렇다.

  1. AccessToken 만료 후 인가 요청
  2. 해당 오류를 포착해서 인가 에러인지 체크
  3. RefreshToken으로 AccessToken 재발급 요청
  4. 발급 받은 AccessToken을 state에 재저장
  5. 방금 실패했던(error) API를 재요청

코드로 확인하면 ?!

여기서 민감한 정보 포함을 승인한다는 뜻의 credentials: “include” 옵션을 추가해야한다.
만약 credentials: “include” 이 없다면 refreshToken을 쿠키에 못담을 뿐만아니라 쿠키에 담겨있는것들도 백엔드로 전송이 되지 않기 때문에 꼭!!

위의 코드에서 유난히 생소한 코드가 보이는데
fromPromise.. 얘는 뭘까??

기존에 흔히 볼 수 있던 promise는 비동기 작업을 도와준다.
fromPromise는 Observable타입을 받을 수 있는 도구라고 한다.

그럼 Observable은 무엇인가??
옵저버블은 연속적인 비동기 작업을 도와주는 도구이다.
요청을 빠르게 여러번 보낸다는 개념!

예를들어 우리가 페이지네이션의 페이지를 순차적으로 빠르게 누른다고 생각해보자.
2번 페이지를 누르자마자 빠르게 3번 페이지를 누르면 어떻게 되는가?
2번 페이지를 보여준 후, 3번 페이지를 보여주는가?
인터넷 환경이나 누르는 속도마다 차이는 있겠지만 3번 페이지를 바로 보여주는 것이 사용자 경험에 더 좋을 것이다.
따라서 2번 페이지를 취소하고 3번 페이지 요청을 보내 3번 페이지를 보여주도록할 때 옵저버블을 사용한다.

따라서 fromPromise는 onError라는 함수가 return타입이 Observable타입이기 때문에 아폴로에서 지원해주는 fromPromise를 사용해주는 것이다.
promise타입을 Observable타입으로 바꿔주는 도구인 것이다.

로그인을 구현하면서 예상되었던 트러블슈팅이 존재했다..^^;;

엑세스토큰을 recoil로 전역적으로 관리해주면서 리프레시토큰을 발급하는 과정까지 수업자료를 참고하면서 코드를 작성했는데 쿠키에 저장이 안되는 거다..
도저히 이유를 모르겠어서 코드 한줄 한줄 읽어보았다.

문제점을 다시 생각해보았다.

"왜 리프레시토큰이 발급되지 않지?"
"왜 발급되어야할 토큰이 쿠키에 담기지 않지?"
"...쿠키?"
"쿠키에 왜 저장이 안되지??"
"쿠키에 저장하려면 필요한 것이 뭐였더라?"

하고 부트캠프에서 수업을 들으며 필기했던 내용을 다시 읽어보았다.

필기 내용에서 찾아보니
credentials: “include” 를 꼭 추가해 주어야 한다는 것!!
하지만 이미 추가해주었다...

도대체 뭘까... 다시 생각해보았다.

"쿠키를 사용하는 이유가 뭐더라?"

로컬/세션 스토리지보다 안전하기때문이지..

"왜 안전하지?"

https 통신을 하기때문에 비교적 안전하다..

???

!!!

연결된 백엔드 서버 주소를 확인해보았다.

http로 적혀있더라구요..
https로 변경하니 쿠키에 토큰이 아주 잘 담겼습니다.. ㅎㅎ;

어떻게 보면 사소한 실수지만
개발자들이 마주한 문제들이 다 이런 식인 것 같다.
코드 한글자만 잘못 작성해도 실행이 안되는 것이 코딩이기때문에
사소하지만 중요하고 발견하기 힘들다..

이번에 실수를 접하면서 생각한 것은
문제가 발견되었을 때 어떤 코드가 잘못되었는지를 코드를 읽으면서 찾으려고 애쓰는 것보다
내가 마주한 문제가 무엇이고, 이 문제를 어디에서 발견할 수 있으며 무엇때문에 안되는 것인지를 찾는 것이 중요한 것 같다는 생각을 했다.
그동안 문제가 있으면 먼저 오타가 있는지 애꿎은 코드만 읽어서 바로 해결할 수가 없었던 것 같다.

이번 문제에서 어떤 문제가 있는지 하나하나 생각해보고
혼자 던지는 질문에 꼬리에 꼬리를 물며 생각해보니 실수를 찾을 수 있었던 것 같다.

그만큼 작성한 코드에 대한 이해도가 높을 수록 에러를 캐치하기 쉬운 것이다.

다음 트러블슈팅이 있을 때에는 이번 경험보다 빨리 에러를 캐치하고 해결할 수 있겠지..?

profile
no record no memory

2개의 댓글

comment-user-thumbnail
2023년 5월 14일

화이팅입니다😊

1개의 답글