[React + Spring Boot] JWT + 소셜 로그인 (1)

susu·2022년 8월 22일
8

JWT + 소셜 로그인

목록 보기
1/3
post-thumbnail
post-custom-banner

코드를 짜면서 수정하거나 보완하면 좋을만한 것들에 대해 메모해둔게 많아서,
아예 글로 과정을 정리해보려 한다.
코드는 이미 잘 짜여진 코드들이 많이 나와있기 때문에,
코드 자체보다는 생각의 흐름을 기록하려 한다.

생각보다 이해하고 공부해야 할 것들이 많아서 중구난방 복잡한 글이 될 수도 있을 것 같지만, 나처럼 막막했던 사람들에게 도움이 되길 바랍니다.
(그리고 나중에 내가 쓴 글 다시 보는 거 재밌음 🥴)

참고하면 좋은 글들

한달동안 에러들과 부딪히며 구글링을 많이 했는데,
그중에서도 도움이 많이 됐다 싶은 글들을 모아봤다.

🔑 로그인 프로세스

  • ID/PW를 이용하는 폼(Form) 타입의 로그인 방식이 아닌,
    OAuth2 인증 소셜 로그인으로 진행한다.
  • 세션 로그인이 아닌 JWT 발급 방식으로 진행한다.
    JWT 방식은 보안에 강점이 있지만 백이나 프론트나 처리해야 할 로직이 더 많다.
    번거롭기야 하겠지만 예전부터 나한텐 백엔드 = 토큰 재발행! 의 이미지가 강했어서 도전해보고 싶었다.
  • 개발자 문서가 친절하기로 유명한 카카오의 REST API 가이드를 따라가며 구현했다.
  • 구글 로그인도 구현할 계획이지만 이 글에서는 카카오 로그인을 기준으로 작성한다.

전체적인 과정

우선 로그인 과정에서 개발자와 카카오 API 서버와의 상호작용을 이해한대로 정리해보았다.

액세스 토큰이니... 리프레쉬 토큰이니.. 인가코드니...
이해하기 복잡하겠지만 전체적인 흐름은 이게 끝이다.
이것만 이해하면 훨씬 생각하기 수월해진다.

전체적인 로그인 로직에 대해서도 생각해봐야 한다.
아래는 내가 생각한 진행 과정이다.
의식의 흐름대로 적었기 때문에 틀릴 수 있음 주의 🚨

  1. 프론트로 로그인 요청이 들어온다 (= 로그인 버튼을 누름)

  2. 인가 코드가 나오면, 프론트는 이걸 일단 백으로 보낸다.
    (엔드포인트 /login/kakao)

  3. 백에서는 인가 코드를 가지고 카카오 서버에서 access token 을 받아온다.

  4. 백에서 access token 으로 카카오 서버에서 회원 정보를 조회한다.

  5. 요청한 회원 정보가 백으로 들어온다.

  6. 백은 이 회원이 DB상에 존재하는 회원인지를 판단하고, 존재하지 않는다면 회원 정보를 DB에 저장한다.

  7. 로그인 '요청'에 대한 '응답' 헤더에 JWT을 담아 프론트에게 보낸다.

  8. 이때 백에서 발행한 JWT 자체에도 만료 시간이 있고,
    프론트에서 새로고침을 하면 받아온 토큰이 사라지기 때문에
    access token (카카오 access token 아님) 과 refresh token을 분리하는 로직을 추가적으로 수행한다.
    8-1. 프론트가 백 DB에 접근할 수 있는 건 access token 이다.
    8-2. access token은 만료 주기가 짧으며, 만료나 새로고침이 일어날 때마다 refresh가 일어나 access token을 재설정한다 (refresh token) -> silent refresh 방식으로 로그인을 유지하는 것이 좋을 듯.

  9. access token을 받아와서 DB에 접근한다.
    9-1. 로그인을 시도한 계정의 정보가 DB에 있으면 (= 이미 가입된 회원) 홈 화면으로 리디렉트 시키기
    9-2. 최초 로그인인 경우 홈 화면으로 리디렉트시킨 후, 별명과 프로필 사진 설명하는 모달창 띄우기
    -> 이때 프론트에서 헤더에 토큰을 넣어 api 엔드포인트로 보내면, 백이 데이터를 담아 응답하는 방식으로 통신한다.

프론트엔드(클라이언트)가 할 일

  • 백으로 인가 코드를 따서 보내줘야 한다.

  • JWT를 받아오고, access token과 refresh 토큰을 관리해야 한다.
    -> http-only cookie를 이용해 토큰으로 계속 서버에 조회 요청을 할 것인지,
    담아온 정보를 localstorage에 저장해서 관리할 것인지 선택해야 한다.
    나는 브라우저에 남아있는 쿠키를 이용해 refresh token을 받아오는 방식을 택했다.

  • 로그인 유무에 따라 다른 컴포넌트를 렌더링해야 한다.
    이를 위해선 redux를 이용해 전역 상태관리가 필요할 것 같다.

3. 백엔드(서버)가 할 일

  • 프론트에서 넘어온 인가 코드로 카카오 서버에 정보 조회를 요청한다.

  • 응답으로 받은 정보를 DB에 저장한다.

  • 모든 유효한 로그인 요청에 대해 access token 과 refresh token 을 발급한다.

  • refresh token은 DB에 저장해야 한다.
    -> 초기에는 access token만 발급해 백단에 접근하는 방식으로 구현했지만,
    이왕 하는 거 제대로 해보고 싶어서 refresh token을 이용하는 전체적인 로직을 구현했다.

  • 프론트에서 넘어온 access token의 유효성을 검증하고, 데이터를 응답한다.

post-custom-banner

0개의 댓글