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

25. 이메일, 패스워드로 계정 만들기, 그리고 로그인

그랜파 개발자 2025. 5. 1. 22:03

이메일, 패스워드로 계정 만들기

Vuetify Vue 3 + Pinia + Firebase Authentication을 사용해서
"이메일/패스워드로 계정 만들기 컴포넌트(Register.vue)"와
"이메일/패스워드로 로그인 컴포넌트 (Login.vue)"입니다.

 

🧩 구성 요약

  • v-form으로 유효성 검사를 처리
  • Vuetify v-text-field, v-btn 등을 사용해 깔끔한 UI 구성
  • mdi-email, mdi-lock 아이콘 포함
  • authStore에 있는 register() 호출

📁 src/views/Register.vue

<!-- src/views/Register.vue -->
<template>
  <v-container class="fill-height" fluid>
    <v-row align="center" justify="center">
      <v-col cols="12" sm="8" md="4">
        <v-card elevation="10" class="pa-4">
          <v-card-title class="text-h6 font-weight-bold">계정 만들기</v-card-title>
          <v-card-text>
            <v-form @submit.prevent="onRegister" ref="formRef" v-model="formValid">
              <v-text-field
                v-model="email"
                label="이메일"
                type="email"
                :rules="emailRules"
                prepend-inner-icon="mdi-email"
                required
              />

              <v-text-field
                v-model="password"
                label="비밀번호"
                type="password"
                :rules="passwordRules"
                prepend-inner-icon="mdi-lock"
                required
              />

              <v-btn :loading="auth.loading" type="submit" color="primary" class="mt-4" block>
                회원가입
              </v-btn>
            </v-form>
          </v-card-text>
          <v-card-actions class="justify-center">
            <RouterLink to="/login">이미 계정이 있으신가요?</RouterLink>
          </v-card-actions>
        </v-card>
      </v-col>
    </v-row>
  </v-container>
</template>

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

const auth = useAuthStore();

const email = ref('');
const password = ref('');
const formValid = ref(false);
const formRef = ref(null);

const emailRules = [
  (v) => !!v || '이메일은 필수입니다.',
  (v) => /.+@.+\..+/.test(v) || '올바른 이메일 형식이 아닙니다.',
];

const passwordRules = [
  (v) => !!v || '비밀번호는 필수입니다.',
  (v) => v.length >= 6 || '비밀번호는 최소 6자리 이상이어야 합니다.',
];

const onRegister = () => {
  if (formRef.value?.validate()) {
    auth.register(email.value, password.value);
  }
};
</script>

<style scoped>
.fill-height {
  min-height: 100vh;
}
</style>

이메일과 비밀번호로 로그인

Vue 3 + Vuetify + Firebase + Pinia 기반의 로그인 컴포넌트 (Login.vue)입니다.
이메일과 비밀번호로 로그인하는 방식이며, Google 로그인 버튼도 추가합니다.

📁 src/views/Login.vue

<!-- src/views/Login.vue -->
<template>
  <v-container class="fill-height" fluid>
    <v-row align="center" justify="center">
      <v-col cols="12" sm="8" md="4">
        <v-card elevation="10" class="pa-4">
          <v-card-title class="text-h6 font-weight-bold">로그인</v-card-title>
          <v-card-text>
            <v-form @submit.prevent="onLogin" ref="formRef" v-model="formValid">
              <v-text-field
                v-model="email"
                label="이메일"
                type="email"
                :rules="emailRules"
                prepend-inner-icon="mdi-email"
                required
              />

              <v-text-field
                v-model="password"
                label="비밀번호"
                type="password"
                :rules="passwordRules"
                prepend-inner-icon="mdi-lock"
                required
              />

              <v-btn :loading="auth.loading" type="submit" color="primary" class="mt-4" block>
                로그인
              </v-btn>

              <v-btn variant="outlined" block class="mt-2" @click="auth.googleLogin">
                <v-icon start>mdi-google</v-icon>
                구글로 로그인
              </v-btn>
            </v-form>
          </v-card-text>
          <v-card-actions class="justify-center">
            <RouterLink to="/register">계정이 없으신가요?</RouterLink>
          </v-card-actions>
        </v-card>
      </v-col>
    </v-row>
  </v-container>
</template>

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

const auth = useAuthStore();

const email = ref('');
const password = ref('');
const formValid = ref(false);
const formRef = ref(null);

const emailRules = [
  (v) => !!v || '이메일은 필수입니다.',
  (v) => /.+@.+\..+/.test(v) || '올바른 이메일 형식이 아닙니다.',
];

const passwordRules = [
  (v) => !!v || '비밀번호는 필수입니다.',
  (v) => v.length >= 6 || '비밀번호는 최소 6자리 이상이어야 합니다.',
];

const onLogin = () => {
  if (formRef.value?.validate()) {
    auth.login(email.value, password.value);
  }
};
</script>

<style scoped>
.fill-height {
  min-height: 100vh;
}
</style>