Vue3, Firebase 프로젝트 - 채팅앱 VSignal

24. Firebase Authentication의 주요 기능들을 통합한 Pinia store

그랜파 개발자 2025. 4. 30. 11:17

Firebase Authentication의 주요 기능들을 통합한 Pinia store

Firebase Authentication의 주요 기능들을 Pinia store에 통합합니다.
이 store는 Vue 3과 함께 작동하며,
이메일/비밀번호 회원가입 및 로그인, 로그아웃,
현재 로그인 상태 유지, 비밀번호 변경 및 재설정, 구글 로그인까지 모두 포함합니다.

src/stores/authStore.js

// src/stores/authStore.js
import { defineStore } from 'pinia';
import { ref, computed } from 'vue';
import { useRouter } from 'vue-router';
import {
  createUserWithEmailAndPassword,
  signInWithEmailAndPassword,
  signOut,
  onAuthStateChanged,
  sendPasswordResetEmail,
  updatePassword,
  GoogleAuthProvider,
  signInWithPopup,
  EmailAuthProvider,
  reauthenticateWithCredential
} from 'firebase/auth';
import { auth } from '@/firebase'; // firebase.js에서 auth 객체 import

export const useAuthStore = defineStore('auth', () => {
  const router = useRouter();

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

  const isAuthenticated = computed(() => !!user.value);

  // 회원가입
  const register = async (email, password) => {
    try {
      loading.value = true;
      const userCredential = await createUserWithEmailAndPassword(auth, email, password);
      user.value = userCredential.user;
      router.push('/');
    } catch (error) {
      alert('회원가입 실패: ' + error.message);
    } finally {
      loading.value = false;
    }
  };

  // 로그인
  const login = async (email, password) => {
    try {
      loading.value = true;
      const userCredential = await signInWithEmailAndPassword(auth, email, password);
      user.value = userCredential.user;
      router.push('/');
    } catch (error) {
      alert('로그인 실패: ' + error.message);
    } finally {
      loading.value = false;
    }
  };

  // 로그아웃
  const logout = async () => {
    try {
      await signOut(auth);
      user.value = null;
      router.push('/');
    } catch (error) {
      alert('로그아웃 실패: ' + error.message);
    }
  };

  // 로그인 상태 유지
  const initializeAuth = () => {
    onAuthStateChanged(auth, (currentUser) => {
      user.value = currentUser;
    });
  };

  // 비밀번호 재설정
  const resetPassword = async (email) => {
    try {
      await sendPasswordResetEmail(auth, email);
      alert('비밀번호 재설정 이메일을 보냈습니다.');
    } catch (error) {
      alert('재설정 실패: ' + error.message);
    }
  };

  // 비밀번호 변경
  const changePassword = async (currentPassword, newPassword) => {
    try {
      const credential = EmailAuthProvider.credential(auth.currentUser.email, currentPassword);
      await reauthenticateWithCredential(auth.currentUser, credential);
      await updatePassword(auth.currentUser, newPassword);
      alert('비밀번호가 변경되었습니다.');
    } catch (error) {
      alert('비밀번호 변경 실패: ' + error.message);
    }
  };

  // 구글 로그인
  const loginWithGoogle = async () => {
    try {
      const provider = new GoogleAuthProvider();
      const result = await signInWithPopup(auth, provider);
      user.value = result.user;
      router.push('/');
    } catch (error) {
      alert('구글 로그인 실패: ' + error.message);
    }
  };

  return {
    user,
    isAuthenticated,
    loading,
    register,
    login,
    logout,
    resetPassword,
    changePassword,
    loginWithGoogle,
    initializeAuth,
  };
});

🔧 firebase.js 예시

// src/firebase.js
import { initializeApp } from 'firebase/app';
import { getAuth } from 'firebase/auth';

const firebaseConfig = {
  apiKey: import.meta.env.VITE_FIREBASE_API_KEY,
  authDomain: import.meta.env.VITE_FIREBASE_AUTH_DOMAIN,
  projectId: import.meta.env.VITE_FIREBASE_PROJECT_ID,
};

const app = initializeApp(firebaseConfig);
export const auth = getAuth(app);

💡 사용 예시 (컴포넌트에서)

<template>
  <div>
    <input v-model="email" placeholder="이메일" />
    <input v-model="password" type="password" placeholder="비밀번호" />
    <button @click="register">회원가입</button>
    <button @click="login">로그인</button>
    <button @click="googleLogin">Google 로그인</button>
  </div>
</template>

<script setup lang="ts">
import { ref } from 'vue';
import { useAuthStore } from '@/stores/authStore';

const auth = useAuthStore();

const email = ref('');
const password = ref('');

function register() {
  auth.register(email.value, password.value);
}

function login() {
  auth.login(email.value, password.value);
}

function googleLogin() {
  auth.loginWithGoogle();
}
</script>