코드로 우주평화

Supabase로 SvelteKit에 GitHub 로그인을 구현해보자 본문

나는 이렇게 논다/월간 메이커스

Supabase로 SvelteKit에 GitHub 로그인을 구현해보자

daco2020 2023. 12. 24. 19:29

 

SvelteKit에서 GitHub로그인을 어떻게 구현할 수 있을까요?

 

이번 글에서는 SvelteKit에서 Supabase를 이용해 간단히 Github로그인을 구현해 보도록 하겠습니다.

*SvelteKit: Svelte를 기반으로 한 풀스택 웹 프레임워크

 

 


 

Supabase 란?

 

Supabase 는 Firebase의 대안으로 떠오르는 오픈소스 백엔드 서비스입니다.

 

Supabase의 주요 기능으로는 PostgreSQL 기반의 데이터베이스, 소셜 인증 기능, 실시간 구독과 파일을 저장할 수 있는 스토리지 등이 있습니다.

 

저는 Supabase 의 소셜 인증 기능을 사용해 Github 로그인으로 구현해 보겠습니다.

 

 


 

Supabase 프로젝트 생성

 

먼저 Supabase 홈페이지에 접속하여 프로젝트를 생성해 줍니다.

 

프로젝트 이름과 데이터베이스 패스워드, 지역을 선택하고 Create new project 버튼을 클릭해 줍니다.

 

그러면 Project가 생성되고 왼쪽 두 번째 아이콘(Table edit)을 클릭하면 Public에 아직 테이블이 비어있는 것을 볼 수 있습니다. 소셜 로그인에는 Public 테이블이 필요 없으므로 지금은 그대로 두겠습니다.

 

소셜 로그인을 위해 Authentication의 Providers에서 GitHub을 선택하고 enabled 상태로 바꿔줍니다.

 

그리고 Callback URL (for OAuth) 을 Copy 해주세요.

 

 

해당페이지는 다시 돌아올 예정이니 아직 닫지 말아 주세요 😉

 

 


 

GitHub OAuth App 생성

 

깃헙의 Developer Settings 으로 이동합니다.

 

OAuth Apps의 New OAuth Apps 를 눌러주세요.

 

새로운 OAuth App을 생성하는 화면이 뜰 텐데요. Application name과 Homepage URL을 입력하고, 앞에서 복사해 둔 Callback URL (for OAuth)을 붙여 넣어주세요.

 

이제 Register application을 누르면 새로운 OAuth App 이 생성되고, Client ID와 Client secrets를 확인하실 수 있습니다.

 

확인한 Client ID와 Client secrets를 아까 열어두었던 Supabase의 Authentication페이지로 돌아가 입력하고 save를 해줍니다.

 

 


 

SvelteKit 프로젝트 생성

 

먼저 SvelteKit 프로젝트를 생성하겠습니다. 만약 이미 SvelteKit으로 작업한 프로젝트가 있다면 생략하셔도 됩니다.

 

test-project라는 이름의 SvelteKit 프로젝트를 생성합니다.

npm create svelte@latest test-project

 

생성된 폴더로 들어가 패키지를 설치해 줍니다.

cd test-project && npm install

 

dev 사이트를 열어보겠습니다.

npm run dev

 

http://localhost:5173/ 로 접속하면 아래와 같은 화면이 보입니다.

 

다시 터미널로 돌아와 supabase-js 패키지를 설치해 줍니다.

npm install @supabase/supabase-js

 

 

다음으로 Supabase를 연동해 보겠습니다!

 

 


 

Supabase 연동

 

src/lib/supabaseClient.js 파일을 생성하고 아래 코드를 넣습니다. 아래 코드는 Supabase를 연동하고 Client 객체를 생성하는 코드입니다.

import { createClient } from '@supabase/supabase-js'

const supabaseUrl = import.meta.env.VITE_PUBLIC_SUPABASE_URL
const supabaseAnonKey = import.meta.env.VITE_PUBLIC_SUPABASE_ANON_KEY

export const supabase = createClient(supabaseUrl, supabaseAnonKey)

 

여기서 supabaseUrl 는 Project URL이고, supabaseAnonKey 는 API key입니다. 아까 생성한 Supabase의 test-project 프로젝트 Home 탭으로 가시면 중간쯤에 해당 값들을 알 수 있습니다.

해당 값들을 복사하여 root 경로의 .env 파일에 넣어줍시다.

VITE_PUBLIC_SUPABASE_URL=supabaseUrl
VITE_PUBLIC_SUPABASE_ANON_KEY=supabaseAnonKey

 

import.meta.env 로 환경변수를 불러오는 경우에는 접두어로 VITE_ 를 붙여주어야 합니다. 실수로 환경 변수가 클라이언트에 유출되는 것을 방지하기 위해 VITE_ 접두사가 붙은 변수만 Vite 처리 코드에 노출합니다.

 

 

이제 본격적으로 깃헙 로그인을 구현해 봅시다!

 

 


 

GitHub 로그인 구현

 

root 페이지인 src/routes/+page.svelte 경로로 이동해 줍니다. 기존 코드는 삭제하고 아래 코드를 넣어주세요.

<script>
    import { supabase } from '$lib/supabaseClient';
    import { onMount } from 'svelte';

    let user;

    onMount(async () => {
        user = await currentUser();
    });

    async function currentUser() {
        const { data } = await supabase.auth.getUser();
        return data.user;
    }

    async function signInWithGithub() {
        const { data, error } = await supabase.auth.signInWithOAuth({
            provider: 'github'
        });
    }

    async function signOut() {
        const { error } = await supabase.auth.signOut();
        user = null;
    }
</script>

<div class="signin-container">
    {#if user}
        <img style="width: 100px; height: auto;" src={user.user_metadata.avatar_url} alt="avatar" />
        <button on:click={signOut}>Sign out</button>
    {:else}
        <button on:click={signInWithGithub}>Sign in with GitHub</button>
    {/if}
</div>

<style>
    .signin-container {
        display: flex;
        flex-direction: column;
        justify-content: center;
        align-items: center;
        height: 100vh;
    }
</style>

 

다시 브라우저를 돌아가시면 로그인 버튼이 생겼습니다. Sign in with GitHub 버튼을 클릭해 봅시다!

 

아래처럼 깃헙 로그인 화면이 뜨면 Authorize 버튼을 눌러줍니다.

 

본인의 깃헙 프로필 이미지가 나타난 것을 확인할 수 있습니다. 정상적으로 로그인한 상태가 된 거죠! 👏👏👏

 

만약 로그인이 정상적으로 이루어지지 않는다면 url을 확인해 주세요. redirect url 잘못되었을 수 있습니다.

 

만약 URL이 이상하다면 Supabase의 Authentication으로 돌아가 URL Configuration탭을 확인해 주세요. Site URL이 여러분의 URL 과 일치하는지 확인해주세요. 

 

로그인과 로그아웃이 잘 된다면, 이제 코드가 어떻게 동작하는지 살펴볼까요?

 

 


 

코드 설명

 

임포트 구문:

   import { supabase } from '$lib/supabaseClient';
   import { onMount } from 'svelte';

 

`supabase`: 앞서 생성한 Supabase 클라이언트를 임포트 합니다. 
`onMount`: Svelte의 생명주기 함수입니다. 컴포넌트가 초기화될 때 실행됩니다.

 

 

변수 선언:

   let user;

 

`user`: 현재 로그인한 사용자의 정보를 저장할 변수입니다.

 


onMount 함수:

   onMount(async () => {
       user = await currentUser();
   });

 

이 함수는 컴포넌트가 마운트 될 때 실행됩니다. `currentUser` 함수를 호출해 현재 로그인한 사용자의 정보를 가져오고 `user` 변수에 할당합니다.

 


currentUser 함수:

   async function currentUser() {
       const { data } = await supabase.auth.getUser();
       return data.user;
   }

 

Supabase 인증 API를 통해 현재 로그인한 사용자의 정보를 가져오는 함수입니다.

 


signInWithGithub 함수:

   async function signInWithGithub() {
       await supabase.auth.signInWithOAuth({
           provider: 'github'
       });
   }

 

이 함수는 Supabase의 `signInWithOAuth` 메서드를 이용해 GitHub OAuth를 호출합니다.

 

 

signOut 함수:

   async function signOut() {
       await supabase.auth.signOut();
       user = null;
   }

 

사용자가 로그아웃할 때 호출되는 함수입니다. Supabase의 `signOut` 메서드를 이용해 로그아웃을 처리합니다. 그리고 `user`를 다시 null로 할당해 변수를 초기화합니다.

 

 

HTML과 CSS는 설명은 생략하겠습니다. 😉 

 

 


 

마치며

 

이 글에 제시된 코드는 최대한 쉽게 설명하기 위해 간단히 작성된 코드입니다. 실제 프로젝트에서는 인증 모듈과 유저 호출 로직 등을 적절히 분리하고, 보안과 페이지별 동기화 등 여러 사항 등을 고려해야 합니다.

 

SvelteKit과 Supabase, GitHub Oauth에 대한 내용은 공식문서에도 언급이 되어있습니다. 보다 정확하게 알고 싶다면 아래 첨부한 레퍼런스를 참고해 주세요.

 

이 글은 여러분이 헤매지 않고 보다 쉽게 구현할 수 있도록 일부 내용과 이미지를 추가해 작성한 글입니다. 도움이 되기를 바라며 글을 마치겠습니다. 👋

 

 


 

레퍼런스

 

Use Supabase with SvelteKit
Login with GitHub
Env Variables and Modes