[Vue.js/개발일지] 06. 파이어베이스로 회원가입과 로그인 구현하기
이제부터 백엔드쪽 기능들을 건들여볼까 했다. 근데 나는 아는 것이 없었기에.. 플러터에 사용해봤었던 파이어베이스로구축 해볼까 했다. 그냥 대충 구글링해서 파베 쓰면 되겠지 했었던 나는 죽어있었고..
문제점은 파이어베이스 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)
});
}
}
}
똑같이 공식 문서 카피해서 작업해주었다. 끝.