[뚜벅몽] 카카오 로그인으로 내 동네의 문을 열다! (#2)

gyo_zaa·2025년 3월 29일

뚜벅몽

목록 보기
2/2
post-thumbnail

0. 개요

지금까지 프로젝트를 하면서 항상 자체 회원가입을 통해 진행했었다. 소셜 로그인은 진입 장벽이 높아보였다...ㅎㅎ 인증이 뭐고 인가가 뭐고... 아무것도 모르던 나는 많은 블로그와 카카오 api를 통해 하나씩 깨닫게 되었다. 이 글을 통해 나의 삽질 과정에 대해 적어보고자 한다.

1. 카카오 로그인 기능 구현

1) 로그인 로직

일단, 이번 프로젝트는 간단히 말하면 동네 기반 산책 경로 플랫폼이다. 여기에서 포인트는 동네이다. 동네하면 가장 먼저 떠올릴 수 있는 당근마켓처럼 동네를 지정하여야한다. 따라서, 시작 페이지에서 최초로 회원가입한 경우와 이미 가입되어 있는 경우 로직을 다르게 설정하였다.

1. 로그인 성공 -> 신규 사용자 -> 동네 설정 페이지 -> 홈 화면
2. 로그인 성공 -> 기존 사용자 -> 바로 홈 화면

2) 카카오 로그인 API 초기 설정

kakao developer에서 내 애플리케이션을 추가하고 도메인을 추가하는 과정은 다른 블로그에서도 많이 나와있기 때문에 생략하겠다.

📍 막힌 개념(Redirect URI)

여러 설정을 하는 과정에서 Redirect URI를 등록하는게 있었다. url도 아니고 uri? 도대체 무엇인가??

Redirect URI란, 사용자가 카카오 로그인 과정을 완료한 후, 카카오 서버가 "인증 결과"를 보내줄 웹 주소를 말한다. 쉽게 설명하자면, 우리가 카카오 로그인을 통해 사용자가 인증(로그인)을 성공하면, 카카오 서버는 이 정보를 안전하게 전달하여야 한다. 이를 위해 개발자가 미리 정확한 주소인 URI를 등록해놓는다. 이 주소는 카카오가 여기로 인증 결과를 보내라는 지시를 내리는 역할을 한다.

URL도 웹 주소를 의미하지만, Redirect URI는 보안상의 이유로 매우 엄격하게 관리되며, 카카오 서버는 오직 미리 등록한 Redirect URI로만 정보를 보낼 수 있기 때문에, 잘못된 주소를 등록하면 로그인 과정에서 오류가 발생하게 된다.

3) 카카오 로그인 코드 흐름

(1) 파일 구조

카카오 로그인 관련해서 로그아웃 기능을 제외하고 총 3가지의 파일을 만들었다.

1. Start.jsx
- 초기 로그인 화면을 담당 => 팝업 방식
- Kakao JavaScript SDK를 로드 및 초기화하고, 카카오 로그인 버튼을 제공

2. SocialKakao.jsx
- 카카오 로그인을 또 다른 방식인 리디렉션 방식으로 처리

3. Auth.jsx
- 카카오 로그인 후, Redirect URI로 돌아온 사용자를 처리하는 콜백 페이지로 인증 코드를 받아 액세스 토큰을 획득하고 이를 통해 사용자 상태를 확인한 뒤 적절한 화면으로 이동하는 역할

(2) Start.jsx

1. kakao SDK 초기화

env에서 API 키를 추출하여 만약 이미 SDK가 초기화된 상태라면 window.kakao.cleanup()을 호출하여 기존 인스턴스를 제거하여 중복 초기화를 방지하고 아직 초기화되지 않았다면, window.kakao.init(kakaoKey)를 호출하여 SDK를 초기화합니다.

이 과정은 카카오 로그인 기능이 정상적으로 동작하기 위한 전제 조건으로 SDK가 정확히 초기화되어 있어야 로그인 요청이나 인증 처리에 문제가 없기 때문에 필요합니다.

2. 카카오 로그인 처리 함수

이 함수는 사용자가 카카오 로그인 버튼을 클릭했을 때 카카오 로그인을 진행하는 역할을 합니다.

redirect_uri 변수에 "http://localhost:3000/auth"로 설정하고 kakao SDK가 제대로 초기화되어 있는지 확인한 후, 로그인 처리를 진행합니다.

+) 📍 이때 발생했던 이슈

원래 로그아웃 후 "http://localhost:3000/"로 이동한 후 이 상태에서 바로 카카오 로그인 버튼을 누르면, 브라우저 내에 남아있는 세션이나 캐시 때문에 새 로그인 시도가 제대로 이루어지지 않는 문제가 있었습니다. 심지어 새로고침을 해도... SDK를 초기화를 한번 더 해도... 재로그인이 되지 않았고, 완전히 창을 닫았다가 다시 들어와야지만 새로운 로그인 흐름이 시작되었습니다.

isPopup: true 옵션을 주어 메인 브라우저 창과 분리된 별도의 창에서 로그인을 진행함으로써, 기존에 남아있던 세션 정보나 캐시의 영향을 받지 않고 깔끔한 로그인 흐름을 보장하였습니다.

throughTalk: false 옵션을 주어 카카오톡 앱은 이전 로그인 정보나 캐시를 유지할 가능성이 있어 카카오톡 앱을 통한 인증 과정을 비활성화하여 재로그인 문제를 효과적으로 해결하였습니다.

이를 통해 매번 서비스를 껐다가 켜야하는 번거로움을 해결할 수 있었습니다.

(3) SocialKakao.jsx

1. Kakao SDK 초기화

이 부분은 Start.jsx와 거의 동일하기 때문에 생략하겠습니다.

2. 카카오 로그인 처리 함수

https://kauth.kakao.com/oauth/authorize: 카카오 인증 서버의 엔드포인트로, 사용자가 카카오 로그인 페이지로 이동하게 되는 기본 주소

response_type=code: 인증이 성공하면, 카카오가 브라우저에 인증 코드를 반환하도록 지시

client_id=${restApiKey}: 카카오 API의 REST API 키를 client_id로 사용하여, 어떤 애플리케이션에서 로그인 요청이 이루어졌는지 식별

redirect_uri=${redirectUri}: 인증이 완료된 후 카카오가 사용자를 돌려보낼 주소

restApiKey와 redirectUri가 제대로 설정되어있는지 확인하고 값이 없으면 콘솔에 에러 메시지를 출력하고 alert를 통해 사용자에게 알린 뒤, 함수 실행을 중단한다.
만약, 모든 값이 정상적으로 설정된 경우, window.location.href = kakaoURL을 통해 브라우저의 현재 주소를 로그인 URL로 변경하여 사용자가 카카오 계정으로 인증할 수 있도록 한다.

+) 📍 팝업 방식(Start.jsx), 리디렉션 방식(SocialKakao.jsx) 구분한 이유는?

둘 다 Kakao SDK를 초기화하는 등의 공통기능은 동일하지만 로그인 방식에 차이가 있다.

초기 회원가입 시에는 팝업 방식(Start.jsx)을 통해 사용자가 현재 페이지를 유지하면서 빠르게 회원가입을 진행하고, 이후 로그인을 다시 시도할 때는 리디렉션 방식(SocialKakao.jsx)을 사용해 브라우저의 세션이나 캐시 문제 없이 깔끔한 로그인 절차를 진행할 수 있도록 설계하였다.

(4) Auth.jsx

1. 액세스 토큰 요청

URLSearchParams를 사용해 요청 본문에 필요한 데이터(인증 방식, API 키, Redirect URI, 인증 코드)를 설정하고 fetch를 사용하여 토큰 API에 요청을 보내 응답을 JSON으로 파싱합니다.
이때, 응답에 access_token이 존재하면 사용자의 상태를 확인하는 함수인 checkUserStatus를 호출합니다.

액세스 토큰은 이후 사용자의 인증 상태를 확인하고, JWT 토큰을 발급하기 위한 핵심 정보입니다.

2. 사용자 상태 확인 및 페이지 이동

처음에 설명한대로 기존 사용자인 경우에는 /home으로 이동하고 새로운 사용자인 경우에는 /dongne-setting으로 갔다가 /home으로 이동하게 됩니다.

따라서, /api/auth/kakao api에서 1차적으로 기존에 있는 사용자인지 jwt_token을 통해 확인을 하고 성공하면 /home으로 이동하게 되고

status가 400일 때는 기존 사용자가 아니기 때문에 동네 설정 페이지인 /dongne-setting으로 이동하여

다음과 같이 DongeneSetting.jsx에서 /api/auth/signup api를 호출하여 파라미터로 액세스토큰과 주소코드를 보내 회원가입을 완료하여 /home으로 이동하는 방식으로 처리했습니다.

2. 동네 설정 페이지 구현

1) 초기 상태 및 변수 선언

초기 좌표를 서울특별시청의 좌표인 위도 37.5665, 경도, 126.9780으로 설정하였습니다.

2) 마커 생성 함수

현재 위치를 기준으로 카카오 지도에 마커를 생성하고, 지도 중심을 마커 위치로 이동시켰습니다.

useCallback를 사용하여 currentLocation이 변경될 때마다 새로운 함수를 생성하였습니다.

3) 주소 및 법정동 코드 가져오는 함수

카카오 REST API의 coord2regioncode 엔드포인트를 추출해 현재 좌표에 해당하는 행정구역 정보를 가져옵니다. 그 후 응답에서 region_type이 "B"인 데이터를 찾아 동네 이름과 법정동 코드를 상태에 저장합니다.

+) 📍 이때 발생했던 이슈

클라이언트 측에서는 원활하게 행정구역 정보를 받ㅇ왔지만, 서버 측에서는 동네 설정 기능을 구현하기 위해 SQL 테이블에 법정동 코드를 미리 저장해두고, 클라이언트에서 받은 정보와 비교하여 일치하는 동네만 저장하도록 처리하여야 했기 때문에 임의로 광주 지역의 핵심 동네만 추가해두어 다른 지역은 저장이 안된다는 아쉬움이 있었습니다.

insert into `location` values (1, "풍암동", "2914012800");

4) 동네 정보 재설정 및 저장

사용자가 새로고침 버튼을 누르면 브라우저의 Geolocation API를 통해 현재 위치를 다시 가져와 상태를 업데이트합니다. 이때, 동네 이름과 법정동 코드도 초기화하여 새로운 주소 정보를 가져올 수 있도록 하였습니다.

3. 마무리

카카오 로그인과 동네 설정 페이지 구현을 통해, 사용자가 번거로움 없이 손쉽게 인증하고 자신의 위치 기반 동네를 설정할 수 있도록 했습니다.

profile
닌자가 되자!

0개의 댓글