이전 게시물에서 Supabase에 대한 소개와 프로젝트 생성, 이메일 회원가입 인증과 로그인을 하기 위한 프로젝트 세팅과 구현에 필요한 코드를 설명했습니다.
이번에는 우리가 웹 앱을 개발할 때 소셜 로그인 구현을 함에 있어서 빠지지 않는 카카오 계정을 이용한 로그인을 Supabase에서는 어떻게 구현할 수 있는지 설명하겠습니다.

먼저 Supabase의 대시보드에서 이전에 생성해뒀던 프로젝트로 들어와 왼쪽 사이드바의 Authentication으로 접속해서 Providers를 클릭하여 위의 페이지로 이동합니다.
그럼 우리가 구현해두었던 Email에 Enabled라고 활성화 되어있는 걸 확인할 수 있고 쭉 아래로 내려가보면 구글, 카카오와 같은 Oauth를 지원하는 플랫폼도 사용할 수 있는 걸 알 수 있습니다. 전 이미 구현을 해 둔 상태라 활성화 되어있지만 처음하면 Disabled로 되어있을 것입니다.

Kakao라는 아코디언을 클릭하면 위와 같은 하위 콘텐츠가 나타납니다. 먼저 Enabled를 클릭하여 카카오 로그인을 활성화해주세요. 그 다음, 3개의 입력값을 넣어줍니다.
REST API key와 클라이언트 시크릿이라는 2개의 변수를 설정하려면 등록해둔 카카오 애플리케이션이 있어야 합니다. 콜백 URL은 자동으로 생성이 되어있는데 이건 '내 애플리케이션'에 설정해줘야하는 값입니다.
카카오 개발자센터 - 내 애플리케이션
https://developers.kakao.com/console/app

로그인을 하고 해당 페이지로 오면 이렇게 애플리케이션 추가하기를 눌러서 애플리케이션을 추가할 수 있습니다.

추가하기를 누르면 입력해야 하는 네 개의 항목과 동의항목이 나옵니다.
위 내용대로 적절히 채운 후 동의항목을 체크하고 저장을 누르면 애플리케이션이 생성됩니다.


그 다음 왼쪽 사이드바 메뉴에 '앱 키'를 클릭하여 이동하면 이미지처럼 4개의 키를 확인할 수 있습니다. Supabase에서 필요한 키는 REST API 키이므로 이걸 복사해서

Supabase의 카카오 REST API KEY 인풋 박스에 붙여넣어주면 됩니다.

그리고 다시 사이드바의 플랫폼을 클릭하면 여기서 Web의 도메인을 등록할 수 있습니다. 앱을 배포한 상태라면 배포한 앱의 도메인을 그대로 입력해주면 되고, http://localhost:3000도 줄을 바꿔서 같이 저장해놓습니다. 보통 개발 환경인 로컬호스트와 배포한 앱의 도메인을 병기합니다.

이제 사이드바의 카카오 로그인을 클릭하여 이동합니다. 여기서 활성화 설정을 ON으로 변경합니다. 활성화가 되어있어야 로그인을 구현해 둔 앱에서 정상적으로 로그인을 할 수 있습니다.

아래로 내리면 리다이렉트 URI를 설정하는 영역이 나오는데 여기에 아까 Supabase에서 카카오 로그인을 활성화하면서 자동으로 생성되었던 콜백 URL을 그대로 복사 후 붙여넣어줍니다.

다시 사이드바로 가서 보안을 클릭하여 이동하면 마지막으로 필요한 클라이언트 시크릿을 생성할 수 있습니다. 생성 버튼을 누르면 위처럼 코드가 나오는데 활성화부터 해주고 코드를 복사해서 Supabase에 붙여넣읍시다.

마지막으로 동의항목을 만들어야 할 차례입니다. 개인정보 동의항목 심사 신청을 클릭합니다. 그럼 '비즈 앱 전환'이라는 버튼이 나오는데 또 클릭해주면 됩니다. 클릭하면 앱 아이콘을 등록하라는 안내 문구와 '앱 아이콘 등록'이라는 버튼이 나옵니다. 애플리케이션을 생성할 때 이미 업로드 했다면 바로 전환이 될테고 하지 않았다면 지금 넣으면 됩니다.

넣고 저장한 뒤 일반 탭으로 가있을 텐데 스크롤을 아래로 내려서 '사업자 정보 등록' 버튼을 눌러줍시다. 그리고 이동한 페이지에서 다시 한 번 더 버튼을 눌러줍니다. 그럼 '개인 개발자 비즈 앱 전환'이라는 버튼이 생기는데 이걸 눌러주고 '이메일 필수 동의'를 선택하고 저장을 눌러줍니다. 여기까지 했다면 비즈 앱 전환까지 마쳤습니다.

그리고 동의항목 탭으로 넘어오면 닉네임, 프로필 사진, 이메일을 동의항목으로 설정할 수 있습니다. 필수 동의로 전부 설정하고 동의 목적은 정보 식별을 위해 필요하다는 문구를 추가해주시면 됩니다. 동의 항목까지 설정을 완료하면 Supabase에서도 저장을 눌러주면 구현을 위한 모든 세팅은 끝입니다.
아래는 제가 프로젝트에서 코드로 구현했던 걸 참고용으로 공유해드리겠습니다.
utils/supabase/signinKakao.ts
'use client';
import { createBrowserSupabaseClient } from 'utils/supabase/client';
export const signInWithKakao = async () => {
const supabase = createBrowserSupabaseClient();
const { data, error } = await supabase.auth.signInWithOAuth({
provider: 'kakao',
options: {
redirectTo:`${process.env.NEXT_PUBLIC_API_REQUEST_URI}/auth/callback`
// http://localhost:3000 or https://배포한 도메인
},
});
if (error) alert(error.message);
if (data) console.log(data);
};
카카오 로그인을 요청하는 함수를 구현한 코드입니다. NEXT_PUBLIC_API_REQUEST_URI라는 환경변수에는 http://localhost:3000을 넣어뒀습니다. 배포한 앱에서는 해당 앱의 도메인을 넣어주면 됩니다.
회원가입 함수는 따로 필요없습니다. signInWithOAuth에 회원가입이 되어있지 않은 유저의 로그인 시도를 자동으로 회원가입 과정이 일어나게끔 해주는 기능이 있기 때문에 이 함수 하나만 사용하면 됩니다.
components/kakaoButton.tsx
'use client';
import { signInWithKakao } from 'utils/supabase/signinKakao';
import { Button } from '@mui/material';
export default function KakaoButton() {
return (
<Button
className="bg-yellow-500 font-dpixel text-white hover:bg-opacity-70"
fullWidth
onClick={() => signInWithKakao()}
>
카카오 로그인
</Button>
)
};
로그인 페이지를 여는 버튼을 구현한 컴포넌트 코드입니다. 원래 버튼은 아니고 로그인 폼 컴포넌트로 구현해둔 코드였는데, 참고용으론 버튼 컴포넌트가 적절할 것 같습니다.
app/auth/callback/route.ts
import { NextResponse } from 'next/server';
import { createServerSupabaseClient } from 'utils/supabase/server';
export async function GET(request: Request) {
const { searchParams, origin } = new URL(request.url);
const code = searchParams.get('code');
// if "next" is in param, use it as the redirect URL
const next = searchParams.get('next') ?? '/';
if (code) {
const supabase = await createServerSupabaseClient();
const { error } = await supabase.auth.exchangeCodeForSession(code);
if (!error) {
return NextResponse.redirect(`${origin}${next}`);
}
}
// return the user to an error page with instructions
return NextResponse.redirect(`${origin}/auth/auth-code-error`);
}
이 코드의 로직을 간단히 설명하면, 카카오는 회원가입 정보를 입력하고 동의항목을 모두 동의하면 리다이렉트 URL(콜백 URL)로 쿼리스트링에 code 값을 붙여서 줍니다.
그래서 리다이렉트 URL과 동일한 경로에 페이지 컴포넌트를 생성한 다음, code를 추출하여 이걸 Supabase로 넘겨줘서 로그인 세션을 받아오는 로직을 구현했습니다. 성공한 경우 루트 페이지로 이동시켜줍니다. 회원가입 및 로그인 구현은 마쳤습니다.
components/logout-button.tsx
'use client';
import { Button } from '@mui/material';
import { createBrowserSupabaseClient } from 'utils/supabase/client';
export default function LogoutButton() {
const supabase = createBrowserSupabaseClient();
const handleLogout = async () => {
supabase.auth.signOut();
};
return (
<Button
className="bg-main rounded-xl shadow-md w-[10vw] py-2 hover:bg-opacity-70 transition duration-300 ease-in"
onClick={handleLogout}
>
<span className="text-white text-lg font-dpixel">로그아웃</span>
</Button>
);
}
로그인을 구현했으니 로그아웃도 구현해야 합니다. 로그아웃 컴포넌트는 이메일로 로그인 했을 때 사용했던 로그아웃과 똑같습니다. Supabase가 세션을 제공하므로 Supabase에 signOut 요청을 하면 AuthProvider의 세션이 만료됩니다. 그럼 서버에서 로그아웃은 완료되고, 클라이언트에서도 이전 시간에 본 <Auth/>가 보이도록 처리해뒀으니 클라이언트에서도 로그아웃이 완료됩니다. 이렇게 Supabase에서 카카오 로그인을 구현해보았습니다.