Next.js 15, Supabase 강좌 3편. Github OAuth를 이용한 로그인 구현
** 목 차 **
안녕하세요?
Next.js 15, Supabase 강좌 3편입니다.
지난 시간에는 Next.js 15를 이용한 기본적인 템플릿과 Google OAuth를 이용한 로그인을 구현해 봤는데요.
오늘은 개발자라면 가장 많이 쓰는 Github OAuth를 이용한 로그인을 구현해 보겠습니다.
참고로, 지난 시간 강좌 리스트입니다.
Next.js 15, Supabase 강좌 1편. 유저 인증(Auth)을 위한 Next.js 15와 Supabase 템플릿 만들기
Next.js 15, Supabase 강좌 2편. Google OAuth를 이용한 로그인 구현
Github Developer Settings에서 OAuth Apps 설정
Github 관리자 페이지에 들어가 보면 아래 그림처럼 맨 마지막에 Developer Settings 가 있습니다.
"Developer Settings"를 클릭하면 아래 그림과 같이 3가지나 나오는데요.
우리는 두 번째인 OAuth Apps 설정이 필요합니다.
"OAuth Apps"를 누르면 여러 가지 입력칸이 아래와 같이 나오는데요.
일단 아래와 같이 입력하면 됩니다.
여기서 중요한 게 마지막에 있는 'Authorization callback URL'을 넣어야 하는데요.
이거는 지난 두 번의 강의에서 계속 입력했던 그거입니다.
Supabase 대시보드로 가서 Authentication 부분에서 Providers 부분으로 가면 예전에는 Email과 Google 부분을 "Enabled"해서 사용했었는데 아래처럼 Github 부분을 눌러봅니다.
일단 "Github enabled"를 눌러 활성화해줍시다.
그리고 마지막에 있는 callback url을 복사해서 Github Developer Settings 부분 쪽 'Authorization callback URL'에 넣으시면 됩니다.
이제 Github 쪽에서는 설정이 끝났습니다.
그래서 아래쪽에 있는 'Register Application'을 누르면 아래와 같이 나옵니다.
여기서 필요한 게 'Client ID'와 'Client Secrets'입니다.
'Client ID'는 나와있는 걸 복사해서 Supabase 쪽에 복사해서 넣으면 되고,
'Client Secrets'는 'Generate a new client secret'를 누르면 아래처럼 나오는데요.
이걸 복사해서 Supabase 대시보드의 Github 부분에 넣으시면 됩니다.
위 그림과 같이 다 넣으시고 마지막에 있는 'Save' 버튼을 누르면 완성됩니다.
actions.ts 파일에 Github 관련 코드 넣기
지난 시간까지 만들었던 actions.ts를 보시면 아래와 같습니다.
"use server";
import { Provider } from "@supabase/supabase-js";
import { createClientForServer } from "./server";
import { redirect } from "next/navigation";
const signInWith = (provider: Provider) => async () => {
const supabase = await createClientForServer();
const auth_callback_url = `${process.env.SITE_URL}/auth/callback`;
const { data, error } = await supabase.auth.signInWithOAuth({
provider,
options: {
redirectTo: auth_callback_url,
},
});
console.log(data);
if (error) {
console.log(error);
}
redirect(data.url as string);
};
const signInWithGoogle = signInWith("google");
const signOut = async () => {
const supabase = await createClientForServer();
await supabase.auth.signOut();
};
export { signInWithGoogle, signOut };
위 코드를 자세히 잘 보시면 signInWith 함수가 범용함수가 됩니다.
그래서 아래와 같이 코드를 추가하면 아주 쉽게 signInWithGithub 함수가 완성됩니다.
왜냐하면 Google이나 Github이나 모든 OAuth 2.0 표준을 따르기 때문에 Supabase도 똑같은 함수인 'signInWithOAuth'를 사용합니다.
const signInWithGoogle = signInWith("google");
const signInWithGithub = signInWith("github");
const signOut = async () => {
const supabase = await createClientForServer();
await supabase.auth.signOut();
};
export { signInWithGoogle, signInWithGithub, signOut };
위와 같이 하면 모든 게 마무리되었습니다.
이제 AuthForm에 Sign in with Github 버튼만 만들면 되는데요.
다른 로직은 Google과 모두 똑같습니다.
AuthForm에 Github 로그인 버튼 추가하기
이 부분은 아주 간단합니다.
UI만 추가하면 됩니다.
"use client";
import { signInWithGithub, signInWithGoogle } from "@/utils/supabase/actions";
const AuthForm = () => {
return (
<form className="flex flex-col items-start gap-2">
<button
formAction={signInWithGoogle}
className="border rounded px-2.5 py-2"
>
Sign in with Google
</button>
<button
formAction={signInWithGithub}
className="border rounded px-2.5 py-2"
>
Sign in with Github
</button>
</form>
);
};
export default AuthForm;
어떤가요?
지난 시간에 만들어 놓았던 Google 관련 코드가 똑같이 Github에도 동일하게 적용됩니다.
심지어 'auth/callback/route.ts' 파일도 똑같이 작동합니다.
테스트해 볼까요?
테스트해 보기 전에 아래와 같이 Supabase 대시보드에서 Github 부분이 Enabled 됐는지 확인해 보기 바랍니다.
밑에 "Save" 버튼을 깜박할 때가 많기 때문입니다.
이제 "Sign in with Github" 버튼을 누르면 브라우저가 아래와 같이 바뀌는데요.
Github에 로그인하라고 합니다.
로그인해주면 아래와 같이 나옵니다.
"Authorize" 버튼을 누르면 로그인이 완료됩니다.
참고로 터미널 창에는 아래와 같이 signInWithOAuth 함수에 의해 리턴된 data 값이 아래와 같이 나옵니다.
{
provider: 'github',
url: 'https://lricgtqtchaizkuwbmzw.supabase.co/auth/v1/authorize?provider=github&redirect_to=http%3A%2F%2Flocalhost%3A3000%2Fauth%2Fcallback&code_challenge=Ls9rD4SM9ISZVSzrlqyIwzo52we5IMDVnTd4FtMhe4E&code_challenge_method=s256'
}
역시나 url 부분에 보면 모든 OAuth 앱이 그렇듯이 code 값을 가지고 있습니다.
이 code값이 왜 중요하냐면 처음에 발행한 code값을 Supabase와 Github에서 비교하기 때문입니다.
이 code 값이 맞으면 Github OAuth 앱에서 액세스 토큰, 리프레시 토큰을 Supabase에 리턴해 주거든요.
이제 위와 같이 로그인된 걸 확인하실 수 있을 겁니다.
어떤가요?
OAuth 관련 로직은 OAuth 2.0을 따르면 Google이나 Github이나 같습니다.
중요한 거는 callback URL을 양쪽으로 교환해 주고, code 값을 리턴해 주면 그 code 값으로 실제 액세스 토큰을 얻는 signInWithOAuth 함수를 실행시키는 여러분만의 callback 라우팅만 만들어 주면 됩니다.
그러면 다음 시간에는 유저 이메일과 패스워드 방식인 전통적인 방식의 Supabase 로그인을 구현해 보도록 하겠습니다.
그럼.