Vue 3와 Firebase 이메일 인증: 토큰 기반 인증 흐름

한눈에 보기

Firebase Authentication은 이메일 인증을 서버 구현 없이 제공하는 관리형 인증 서비스다. ID 토큰과 리프레시 토큰의 흐름, Vue 3 컴포저블 통합, 라우터 가드와 세션 유지, 보안 주의점을 원리 중심으로 정리한다.

최종 업데이트 2026.09.17

Firebase Authentication(파이어베이스 인증)은 이메일과 비밀번호 기반 인증을 서버 구현 없이 제공하는 구글의 관리형 인증 서비스다. Vue 3(뷰 3) 애플리케이션은 Firebase 클라이언트 SDK를 통해 회원 가입, 로그인, 세션 유지를 처리하고, 인증 결과로 받은 ID 토큰(ID token)으로 보호된 자원에 접근한다. 이 문서는 특정 버전의 설치 절차 대신 인증 흐름의 원리와 Vue 3 Composition API(컴포지션 API) 통합 방법을 중심으로 설명한다.

Firebase Authentication의 역할

Firebase Authentication은 BaaS(Backend as a Service) 형태의 인증 서비스로, 비밀번호 해싱과 저장, 토큰 발급과 갱신, 이메일 검증 메일 발송 같은 인증 서버의 책임을 대신 맡는다. 개발자는 비밀번호 유출 리스크를 직접 관리하지 않아도 되고, 인증 서버를 만들고 운영하는 비용을 아낄 수 있다. 인증에 성공하면 Firebase는 JWT(JSON Web Token) 형식의 ID 토큰과 리프레시 토큰(refresh token)을 발급한다. ID 토큰은 약 1시간 뒤 만료되는 단기 자격 증명이고, 리프레시 토큰은 만료된 ID 토큰을 새로 받아 오는 용도이며 SDK가 갱신을 자동으로 처리한다.

이메일 인증의 전체 흐름

  1. 사용자가 이메일과 비밀번호를 입력하면 클라이언트가 createUserWithEmailAndPassword를 호출해 계정을 만든다.
  2. Firebase가 비밀번호를 해시로 저장하고 ID 토큰과 리프레시 토큰을 돌려준다.
  3. 이후 로그인은 signInWithEmailAndPassword로 처리하며 성공 시 같은 형태의 토큰을 받는다.
  4. SDK가 토큰을 브라우저 저장소에 보관하고, 인증 상태 변화는 onAuthStateChanged 콜백으로 통지한다.
  5. 백엔드 API를 호출할 때는 Authorization 헤더에 ID 토큰을 실어 보내고, 서버는 Admin SDK(어드민 SDK)로 토큰 서명을 검증한 뒤 요청을 처리한다.

여기에 더해 sendEmailVerification으로 이메일 소유 확인 메일을, sendPasswordResetEmail로 비밀번호 재설정 메일을 보낼 수 있다. 두 기능 모두 메일 발송 인프라를 Firebase가 대신 제공한다.

Vue 3 컴포저블로 통합하기

Vue 3에서는 인증 로직을 컴포저블(composable) 함수로 추출해 어느 컴포넌트에서든 같은 인증 상태를 구독하게 만드는 패턴이 일반적이다.

// useAuth.js
import { ref } from 'vue';
import {
  getAuth,
  createUserWithEmailAndPassword,
  signInWithEmailAndPassword,
  onAuthStateChanged,
  signOut,
} from 'firebase/auth';

const user = ref(null);
const ready = ref(false);

onAuthStateChanged(getAuth(), (current) => {
  user.value = current;
  ready.value = true;
});

export function useAuth() {
  const signUp = (email, password) =>
    createUserWithEmailAndPassword(getAuth(), email, password);
  const signIn = (email, password) =>
    signInWithEmailAndPassword(getAuth(), email, password);
  const logout = () => signOut(getAuth());

  return { user, ready, signUp, signIn, logout };
}

user와 ready를 모듈 최상위에 두었기 때문에 이 컴포저블을 호출하는 모든 컴포넌트가 하나의 인증 상태를 공유한다. 컴포넌트는 반응형 참조인 user만 지켜보면 되고, 로그인 여부에 따른 화면 분기는 템플릿에서 자연스럽게 처리된다.

라우터 가드와 세션 유지

보호가 필요한 페이지는 Vue Router(뷰 라우터)의 내비게이션 가드에서 인증 여부를 확인해 미로그인 사용자를 로그인 페이지로 보낸다. 이때 흔한 함정이 있다. 새로고침 직후에는 SDK가 저장된 자격 증명을 아직 복원하기 전이라 user가 잠시 null이다. 이 순간의 값만 보고 판단하면 정상적으로 로그인한 사용자도 로그인 페이지로 튕겨 나간다. 그래서 onAuthStateChanged의 첫 번째 호출이 끝났음을 뜻하는 ready 같은 플래그를 두고, 그 이후에 인증 여부를 판정해야 한다.

보안 관점에서 주의할 점

  • Firebase 설정에 들어가는 apiKey는 프로젝트를 식별하는 공개 값이지 비밀 키가 아니다. 실제 접근 통제는 보안 규칙과 서버 측 토큰 검증이 담당한다.
  • 클라이언트의 로그인 상태는 화면 제어용일 뿐이다. 백엔드는 요청마다 ID 토큰의 서명과 만료를 직접 검증해야 하며, 이 검증 없이는 API가 보호되지 않는다.
  • auth/email-already-in-use 같은 오류 코드는 한국어 안내 문구로 매핑해 보여 주되, 특정 이메일의 가입 여부를 유추할 수 있는 정보 노출은 최소화한다.
  • 이메일 소유가 확인된 사용자만 핵심 기능을 쓰게 하려면 user 객체의 emailVerified 값을 함께 확인한다.

면접에서 이렇게 물어본다

  • Firebase Authentication을 도입하면 직접 인증 서버를 구축할 때와 비교해 무엇을 얻고 무엇을 포기하는가.
  • ID 토큰과 리프레시 토큰의 역할 차이와 갱신 흐름을 설명해 보라.
  • 클라이언트에서 로그인 상태를 확인하는 것만으로 API를 보호할 수 없는 이유는 무엇인가.
  • 새로고침 직후 인증 상태가 잠시 비어 있는 문제를 라우터 가드에서 어떻게 다루는가.
  • Firebase의 apiKey가 노출되어도 괜찮다고 말하는 근거는 무엇인가.
React / Vue 문서 전체 보기

이 개념, 내 코드에서는 어떻게 물어볼까요

데브핏(DevFit)에 채용공고 URL을 붙여 넣고 레포지토리를 연결하면, 내가 쓴 커밋에서 예상 질문과 어필 포인트를 만듭니다. 하루 10회까지 무료입니다. 합불 판정이나 지원자 랭킹은 만들지 않고, 최종 판단은 사람이 합니다.

공고 넣고 시작하기