Supabase auth-helpers 말고 @supabase/ssr 써야 하는 이유 (Next.js App Router 기준)

Supabase로 Next.js 인증을 구현하려다 보면 @supabase/auth-helpers-nextjs@supabase/ssr 사이에서 고민하게 됩니다. 결론부터 말하면 auth-helpers는 이미 deprecated(지원 중단)된 패키지예요. 이 글에서는 왜 @supabase/ssr로 갈아타야 하는지, 실제 삽질 경험을 바탕으로 설명합니다.


🤔 처음엔 auth-helpers-nextjs로 시작했다

Supabase 인증을 붙이려고 구글링을 하면 나오는 글 대부분이 @supabase/auth-helpers-nextjs 기준으로 작성되어 있어요. 자연스럽게 이걸 먼저 설치했고, 공식 문서도 예전엔 이걸 기본으로 소개했으니까요.

그런데 막상 써보니 뭔가 자꾸 구조가 꼬이는 느낌이었어요. App Router랑 잘 안 맞는 것 같고, middleware에서 세션 처리가 이상하게 동작하고… 결국 공식 문서를 다시 찾아보다가 충격적인 걸 발견했어요.

# npm 패키지 페이지에 이렇게 써있다
# Package Consolidation Notice:
# The @supabase/ssr package replaces the deprecated @supabase/auth-helpers-* packages.

💥 이미 deprecated였던 거예요. auth-helpers 계열 패키지 전체가 @supabase/ssr로 통합됐고, 더 이상 적극적으로 개선되지 않아요.


📦 두 패키지, 뭐가 다른 거야?

프론트엔드 입문자 입장에서 쉽게 설명하면 이래요.

예전에 Supabase는 프레임워크마다 별도 패키지를 만들어서 배포했어요.

  • Next.js 쓰면 → @supabase/auth-helpers-nextjs
  • React 쓰면 → @supabase/auth-helpers-react
  • SvelteKit 쓰면 → @supabase/auth-helpers-sveltekit

근데 이렇게 쪼개놓으니까 관리가 힘들고, 프레임워크마다 API가 미묘하게 달라서 혼란이 생겼어요. 그래서 “그냥 하나로 합치자”는 결론이 난 게 @supabase/ssr이에요.

항목auth-helpers-nextjs@supabase/ssr
현재 상태⚠️ Deprecated (지원 중단)✅ 현재 공식 권장
구조Next.js 전용프레임워크 독립적
App Router 지원제한적완전 지원
Server / Client 구분모호함명확하게 분리됨
middleware 연동불편함공식 패턴으로 쉽게 가능
앞으로의 업데이트❌ 없음✅ 계속 개선 중

🔄 함수 이름도 다 바뀌었다

기존에 auth-helpers에서 쓰던 함수들이 @supabase/ssr에서는 이름이 바뀌었어요. 마이그레이션 할 때 헷갈리는 부분이라 정리해둘게요.

auth-helpers-nextjs (구)@supabase/ssr (신)어디서 쓰나
createMiddlewareClientcreateServerClientmiddleware.ts
createClientComponentClientcreateBrowserClient클라이언트 컴포넌트
createServerComponentClientcreateServerClient서버 컴포넌트
createRouteHandlerClientcreateServerClientRoute Handler (API)

👉 서버 쪽에서 쓰던 것들은 이제 전부 createServerClient 하나로 통일됐어요. 훨씬 심플해졌죠?


⚙️ @supabase/ssr 실제 설치 & 기본 세팅

말이 길었는데 실제로 어떻게 쓰는지 보여드릴게요. 초보자도 따라할 수 있게 처음부터 설명할게요.

1단계: 패키지 설치

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

2단계: 환경변수 설정

프로젝트 루트에 .env.local 파일을 만들고 아래 내용을 채워요. Supabase 대시보드 → Settings → API에서 값을 복사하면 돼요.

NEXT_PUBLIC_SUPABASE_URL=https://xxxxxxxxxxxx.supabase.co
NEXT_PUBLIC_SUPABASE_ANON_KEY=your-anon-key-here

3단계: 클라이언트 유틸 파일 만들기

@supabase/ssr은 사용하는 환경에 따라 클라이언트를 다르게 만들어야 해요. 크게 두 가지예요.

브라우저(클라이언트 컴포넌트)용utils/supabase/client.ts

import { createBrowserClient } from '@supabase/ssr'

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

서버(서버 컴포넌트 / Route Handler)용utils/supabase/server.ts

import { createServerClient } from '@supabase/ssr'
import { cookies } from 'next/headers'

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

  return createServerClient(
    process.env.NEXT_PUBLIC_SUPABASE_URL!,
    process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!,
    {
      cookies: {
        getAll() {
          return cookieStore.getAll()
        },
        setAll(cookiesToSet) {
          try {
            cookiesToSet.forEach(({ name, value, options }) =>
              cookieStore.set(name, value, options)
            )
          } catch {
            // 서버 컴포넌트에서 호출된 경우 쿠키 쓰기가 안 됨
            // middleware가 대신 처리해줌 → 무시해도 OK
          }
        },
      },
    }
  )
}

💡 왜 두 개를 따로 만드나요?
브라우저와 서버는 쿠키를 다루는 방식이 달라요. 브라우저는 document.cookie로, 서버는 next/headerscookies()로 접근해요. 그래서 환경에 맞는 클라이언트를 각각 만들어줘야 Supabase 세션이 제대로 동작해요.


🙅 auth-helpers 계속 써도 되나요?

당장 에러가 나진 않아요. deprecated라는 게 “지금 당장 동작 안 함”이 아니라 “앞으로 업데이트 안 하겠다”는 선언이거든요.

근데 문제는 이래요.

  • Next.js 버전이 올라가면서 호환성 문제가 생길 수 있어요
  • 보안 패치도 더 이상 없어요
  • 두 패키지를 동시에 쓰면 인증이 꼬이는 버그가 생겨요 (공식 문서에서도 같이 쓰지 말라고 경고해요)

신규 프로젝트라면 처음부터 @supabase/ssr만 쓰세요. 기존 프로젝트라면 마이그레이션을 서두르는 게 좋아요.


✅ 정리

  • @supabase/auth-helpers-nextjs는 이미 deprecated예요 → 새 프로젝트엔 쓰지 마세요
  • @supabase/ssr이 공식 대체제이고, App Router에 맞게 설계되어 있어요
  • 브라우저용 createBrowserClient, 서버용 createServerClient로 역할이 명확하게 분리돼요
  • 두 패키지를 동시에 사용하면 인증이 꼬이니까 반드시 하나만 쓰세요

👉 다음 편에서는 서버 인증에서 절대 헷갈리면 안 되는 getSession vs getUser 차이를 파헤쳐볼게요!


댓글 달기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다

위로 스크롤