[Next.js] Supabase-SSR로 Next.js에 데이터 연동하기

Jane·2024년 8월 15일
1

Next.js

목록 보기
10/12
post-thumbnail

최근에는 주로 앱 개발을 하다보니 Next.js에 대해 많이 까먹고 있다는 생각이 들기도 했고, 예전에 관심이 있어 알아봤다가 자료가 부족해 제대로 적용해보지 못해 아쉬움이 남았던 Supabase를 함께 사용할 수 있는 강의를 듣게 되었다. 강의를 듣고, 학습하면서 기억해두고 싶은 내용들을 남겨두려 이렇게 포스팅하게 되었다.

🌱 이 포스트는 해당 강의를 수강한 후 수업 내용을 기반으로 작성되었으며, 이미지 클릭 시 강의 소개 페이지로 이동합니다.

Supabase에 대한 간단한 설명과 장점은 🦕 Supabase란 무엇인가! 포스트에서 정리해보았으니, 이번 포스트에서는 강의를 통해 Supabase를 실제 웹 프로젝트에 간단하게 적용해보면서 느낀 점에 대해 작성해보고자 한다.

🗃️Supabase로 손쉽게 DB 관리하기

⚡ Database 생성하기

Supabase Database를 사용하면 아래 사진처럼 간단하게 PostgreSQL 기반의 DB 테이블을 구현할 수 있다.

표에 필요한 데이터를 채워주면 아래처럼 원하는 데이터를 담은 테이블이 생성된다.

📥 Supabase CLI 설치하기

Supabase CLI는 프로젝트를 로컬 환경에서 개발하고, Supabase 플랫폼에 배포하고, 데이터베이스 마이그레이션을 처리하고, 데이터베이스 스키마에서 직접 유형을 생성할 수 있는 도구를 제공한다.
아래의 명령어(window 기준)를 통해 Supabase CLI를 설치하면 로컬 환경에서도 supabase initsupabase start만 사용하면 간편하게 Supabase를 실행시킬 수 있게 된다.

npx supabase login

🔠 타입 생성을 위한 스크립트 추가하기

Supabase API는 데이터베이스로부터 파생되므로 타입 안정적인 API 정의를 생성하기 위해 데이터베이스 인트로스펙션을 사용할 수 있다.
아래의 스크립트를 추가해주면 위에서 Supabase를 통해 생성한 테이블의 데이터를 TypeScript 타입으로 정의하고 types_db.ts라는 파일명을 가지는 파일로 다운로드 받을 수 있게 된다.

"scripts": {
  // ...
  "generate-types": "npx supabase gen types typescript --project-id [project_id] --schema public > types_db.ts"
}

project_id 값은 환경변수로 설정한 NEXT_PUBLIC_SUPABASE_URL 값에서 https://.supabase.co 사이의 값을 넣어주면 된다.

🤔 데이터베이스 인트로스펙션(Database Introspection)이란?

  • 데이터베이스의 구조를 자동으로 분석하고 탐색하는 과정을 말한다.
  • 이를 통해 데이터베이스의 다양한 메타데이터(스키마, 테이블, 컬럼, 인덱스, 뷰, 트리거 등)를 파악할 수 있다.

🦕 Supabase SSR

Supabase SSR은 Server-Side 환경에서 Supabase의 다양한 기능을 쉽게 통합하고 사용할 수 있도록 돕는 도구이다.
Supabase에서는 이 단일 라이브러리로 기존 Supabase Database/Auth/Storage가 지원하던 기능들을 모두 사용할 수 있게 하였다.

📥 Supabase SSR 설치하기

npm install @supabase/supabase-js @supabase/ssr

🔠 환경변수 설정하기

# Home > Project API > Project URL
NEXT_PUBLIC_SUPABASE_URL= ''
# Home > Project API > API Key
NEXT_PUBLIC_SUPABASE_ANON_KEY= ''
# Project Settings > API Settings > Project API keys > service_role
# 어드민에서 사용되므로 외부에 절대 공개하면 안 된다.
NEXT_SUPABASE_SERVICE_ROLE= ''
# Supabase DB Password
NEXT_SUPABASE_DB_PASSWORD= ''

Root Directory에 .env 또는 .env.local 파일을 생성하고 위와 같이 환경 변수를 설정해준다.

🪄 Supabase Client 생성하기

Next.js 환경에서 Supabase를 생성하기 위해서는 아래의 두 클라이언트 함수가 구현되어 있어야 한다.
utils 폴더 하위에 supabase 폴더를 생성하고, 아래의 두 유틸 함수를 생성해주면 된다. (함수의 경우 Supabase 공식 문서에서 발췌하였다.)

createBrowserClient

  • 브라우저에서 실행되는 클라이언트 컴포넌트에서 Supabase에 접근할 수 있도록 하는 함수이다.
  • createBrowserClient는 싱글톤 패턴을 사용하여 createClient 함수 호출 횟수에 관계 없이 하나의 인스턴스만을 생성한다.
    • 싱글톤 패턴: 특정 클래스의 인스턴스가 하나만 생성되도록 보장하는 패턴
import { createBrowserClient } from '@supabase/ssr'

export function createClient() {
  return createBrowserClient(
    process.env.NEXT_PUBLIC_SUPABASE_URL!,
    process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!
  )
}

createServerClient

  • 서버에서만 실행되는 서버 컴포넌트, 서버 액션 및 라우트 핸들러에서 Supabase에 접근하기 위한 함수이다.
  • 서버에서 실행되므로, Client-Side에서 필요하지 않은 설정을 포함하지 않고 서버 사이드에 최적화된 Supabase 클라이언트를 생성한다.
  • 요청(Request)과 응답(Response) 객체를 받아 SSR 환경에서 현재 사용자의 인증 상태를 기반으로 데이터를 처리하거나 페이지를 렌더링할 수 있게 한다.
import { createServerClient, type CookieOptions } from '@supabase/ssr'
import { cookies } from 'next/headers'

export function createClient() {
  const cookieStore = cookies()

  return createServerClient(
    process.env.NEXT_PUBLIC_SUPABASE_URL!,
    process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!,
    {
      cookies: {
        // 쿠키 관련 로직이 담긴다.
      },
    }
  )
}

🦾 middleware

Root Directory에 middleware 함수를 정의해주어야 한다. 이를 통해 서버 컴포넌트 대신 쿠키를 사용해 만료된 인증 토큰을 새로 고치고 저장할 수 있다.

  • middleware 설정을 위한 상세한 코드는 여기(공식문서)에서 확인할 수 있다.

  • middleware의 역할

    1. supabase.auth.getUser를 사용하여 인증 토큰을 새로고침한다.
    2. request.cookies.set을 통해 새로고침된 인증 토큰을 서버 컴포넌트에 넘겨서 동일한 토큰에 대한 리프레시를 시도하지 않도록 막는다.
    3. response.cookies.set을 통해 새로고침된 인증 토큰을 브라우저에 넘겨서 이전 토큰을 대체한다.
  • ⚠️ 주의할 점

    • 쿠키에서 가져온 사용자 세션은 누구나 위조 가능하므로 페이지를 보호하려면 각별한 주의가 필요하다.
    • 페이지 및 사용자 데이터 보호를 위해서는 항상 supabase.auth.getUser()를 사용해야 한다. 이는 매번 Supabase Auth 서버에 요청을 보내 인증 토큰을 재검증하기 때문에 사용하기에 안전하다.
    • 서버 관련 코드에서 인증 토큰을 재검증하지 않는 supabase.auth.getSession()을 사용하면 안 된다.

🔥 +) Error Log

Supabase와는 관계 없지만 코드를 치면서 해결했던 오류를 추가로 기록해둔다.

Next.js 14 버전에서 material-tailwind/react 컴포넌트를 사용하자 아래와 같은 메세지와 함께 해당 라이브러리에서 import해온 모든 컴포넌트에 오류가 발생했다.

Property 'crossOrigin' is missing in type ~

찾아보니 라이브러리와 최신 TypeScript 버전 사이에 오류가 있는 것 같았다.

package.json 파일에서 typescript의 버전을 5.2.2로, @types/react의 버전을 18.2.19로 수정하고 npm install을 다시 해줌으로써 해결할 수 있었다.
혼자 작성하는 코드여서 망설임 없이 해당 방법을 사용했지만 팀 프로젝트였다면 다른 해결 방법을 모색하거나 다른 UI Inventory를 사용했을 것 같다.

🔎 References

profile
An investment in knowledge pays the best interest🙃

0개의 댓글