프론트엔드 개발/온누리학교 웹 개발 프로젝트

[Vue.js/개발일지] 06. 파이어베이스로 회원가입과 로그인 구현하기

Jongung 2022. 2. 5. 18:47

이제부터 백엔드쪽 기능들을 건들여볼까 했다. 근데 나는 아는 것이 없었기에.. 플러터에 사용해봤었던 파이어베이스로구축 해볼까 했다. 그냥 대충 구글링해서 파베 쓰면 되겠지 했었던 나는 죽어있었고..

문제점은 파이어베이스 9, Vue 3로 넘어오면서 두 친구 다 문법이 상당히 많이 변경 되었다는 점이다. 나는 이를 알 리가 없었고, 진짜 시간 많이 잡아 먹었던 것 같다. 결국엔  구현 했다는 것이 중요한 거 아니겠나? 회원 가입 페이지 부터 천천히 알아보자. 

<template>
  <div class="container-md">
    <h1>회원가입</h1>

    <form @submit.prevent="userRegistration">
      <div class="mb-3">
        <label
          class="form-label">이름</label>
        <input
          type="name"
          class="form-control"
          v-model="user.name" />
      </div>
      <div class="mb-3">
        <label
          class="form-label">이메일 주소</label>
        <input
          type="email"
          name="email"
          class="form-control"
          v-model="user.email" />
        <div
          id="emailHelp"
          class="form-text">
          이메일은 타인에게 유출되지 않으며, 로그인 시에만 사용 됩니다.
        </div>
      </div>
      <div class="mb-3">
        <label
          class="form-label">비밀번호</label>
        <input
          type="password"
          class="form-control"
          v-model="user.password" />
      </div>
      <button
        @click="register"
        class="btn btn-primary">
        회원가입
      </button>
    </form>
  </div>
</template>

bootstrap 5를 통하여 간단한 로그인 페이지를 만들어주었다. 당연히 container로 묵여있기 때문에 반응형이 되는 웹이다.

<script>
import { getAuth, createUserWithEmailAndPassword, updateProfile } from "firebase/auth";
export default {
  data() {
    return{
      user: {
        email: '',
        password: ''
      }
    }
  },
  methods: {
    userRegistration() {
      createUserWithEmailAndPassword(getAuth(), this.user.email, this.user.password)
      .then((res) => {
      updateProfile(getAuth().currentUser, {
        displayName: this.user.name
        }).then(() => {
          alert('정상 가입 되셨습니다.');
          this.$router.push('/')
          
          })
          .catch((error) => {
            alert(error.message);
        });
      })
      .catch((error) => {
        alert(error.message);
        
      });
    }
  }
}
</script>

파베 9으로 넘어오면서 달라진 점이 있다면, 함수들을 이제 하나하나 객체로 콜 해줘야 한다는 점이다.

완전 달라진 걸 확인 해 볼수 있다. js 인터페이스와 친화되어있던 버전 8을 webpack rollup과 같은 최신형 js 빌드 도구들에 맞춰 새로 개발 했다고 한다. 어짜피 파베 쓸 일이 앞으로 계속 있을 것 같은데 새로운 9버전에 적응 할 필요가 있다고 생각 했다.

import { getAuth, createUserWithEmailAndPassword, updateProfile } from "firebase/auth";

일단 이 세가지를 불러온 이유를 보자. getAuth()는 회원가입 뿐만 아니라, 모든 로그인 관련 Authentication에서 필요한 함수이다. 
그리고 createUserWithEmailAndPassword()는 이메일과 비밀번호를 조합한 로그인 환경에서 꼭 필요한 친구라 데려왔고 이제 updateProfile은 사용자 정보를 담을수 있는 프로필 함수이다. 나중에 사용자 정보 업데이트 할 때도 필요하다고 한다. catch를 switch문으로 모두 잡아줄까 고민도 했으나, 나중에 시간 많으면 하기로 했다. 어짜피 뭐 영어로 에러 코드 떠도 괜찮지 않을까? 이름이 국제 학굔데 뭐... 

다음은 로그인 화면이다. 로그인 화면 또한 똑같은 방식으로 개발했다.

bootstrap 5를 이용하여 회원가입과 똑같이 만들었다.

<template>
  <div class="container-md">
    <h1>로그인</h1>

    <form>
      <div class="mb-3">
        <label
          class="form-label">이메일 주소</label>
        <input
          type="email"
          name="email"
          class="form-control"
          v-model="email" />
      </div>
      <div class="mb-3">
        <label
          class="form-label">비밀번호</label>
        <input
          type="password"
          class="form-control"
          v-model="password" />
      </div>
      <button
        @click="signIn"
        type="submit"
        class="btn btn-primary">
        로그인
      </button>
    </form>
  </div>
</template>

<script setup>
  import { ref } from 'vue'
  import { useRouter } from 'vue-router' 
  import { getAuth, signInWithEmailAndPassword } from "firebase/auth" 

  const email = ref('')
  const password = ref('')
  const auth = getAuth()
  const router = useRouter()
  const errMsg = ref()
  const signIn = () => {
    signInWithEmailAndPassword(auth, email.value, password.value)
    .then((userCredential) => {
    // Signed in
    const user = userCredential.user;
    router.push('/')
    // ...
    })
    .catch((error) => {
      switch (error.code) {
          case 'auth/invalid-email':
              errMsg.value = '이메일을 잘못 입력 하셨습니다.'
              break
          case 'auth/user-not-found':
              errMsg.value = '존재하지 않는 이메일 주소입니다.'
              break
          case 'auth/wrong-password':
              errMsg.value = '비밀번호를 잘못 입력 하셨습니다.'
              break
          case 'auth/too-many-requests':
              errMsg.value = '접속 시도를 너무 많이 하셨습니다.'
              break
          default:
              errMsg.value = '이메일 혹은 비밀번호가 틀렸습니다.'
              break
        }
    alert(errMsg.value);
    console.log(error.code)
    });
  }
  

</script>



<style scoped lang="scss">
  .container-md{
    h1{
      margin-bottom: 50px;
      font-weight: 600;
    }
    input{
      width:50%;
    }
    font-family: 'Nanum Gothic', sans-serif;
    padding-top: 80px;
    padding-bottom: 80px;
  }

  @media(max-width: 1500px){
    .container-md{
    input{
      width:100%;
    }
  }
  }
</style>

로그인은 뷰 형태의 script 파일 대신 setup을 사용하여 js 기본 문법과 똑같이 만들었다. 회원가입보단 로그인 빈도수가 훨씬 많을 것 같아, switch case문으로 작업 해주었다.

  import { getAuth, signInWithEmailAndPassword } from "firebase/auth"

이번엔 Create가 아닌 Sign으로 가져왔다. 물론 파베 공식 문서에서 하란대로 작업 했을 뿐이다.

 

v-if else-if로 로그인 회원가입 자리에 이름과 로그아웃을 만들어 주었다.

			<li
            class="nav-item login"
            v-if="user">
            <div class="user_name nav-link">
              {{ user.displayName }}
            </div>
            <RouterLink
              to="/"
              class="nav-link"
              @click="signOut()">
              로그아웃
            </RouterLink>
          </li>
          <li
            class="nav-item login"
            v-else-if="user == null">
            <RouterLink
              to="/auth/Register"
              class="nav-link">
              회원가입
            </RouterLink>
            <RouterLink
              to="/auth/login"
              class="nav-link">
              로그인
            </RouterLink>
          </li>
import { getAuth, onAuthStateChanged, signOut  } from "firebase/auth";
  export default {
    data() {
      return {
      user: false
      }
    },
created() {
      onAuthStateChanged(getAuth(), (user) => {
      if (user) {
      this.user = user
    // User is signed in, see docs for a list of available properties
    // https://firebase.google.com/docs/reference/js/firebase.User
      const uid = user.uid;
    // ...
      } else {
      this.user = null;
    // User is signed out
    // ...
        }
      });
    },
    methods: {
      signOut(){
        signOut(getAuth()).then(() => {
          this.$router.go();
        }).catch((error) => {
          console.log(error)
      });
    }
  }
}

똑같이 공식 문서 카피해서 작업해주었다. 끝.