์ด์ ํ์๊ฐ์
๋ ์ ์ ๋ฅผ ๋ก๊ทธ์ธ ์งํ์ ํ ํ ํํ์ด์ง๋ก ์ด๋ํ๊ฒ ๋ง๋ค์ด์ค๊ฑฐ์
๋ก๊ทธ์ธ๋ ๊ฐ์
ํ๊ธฐ์ ๋์ผํ๊ฒ
๋ก๊ทธ์ธ ์ค์ผ๋๋ ๋ฒํผ์ ํด๋ฆญํ์ง ๋ชปํ๋๋ก ํ๋ค.
<button v-if="loading" class="w-96 rounded bg-light text-white py-4">
๋ก๊ทธ์ธ ์ค์
๋๋ค.
</button>
<button
v-else
@click="onLogin"
class="w-96 rounded bg-primary text-white py-4 hover:bg-dark"
>
๋ก๊ทธ์ธ
</button>
1. auth์ signInWithEmailAndPassword ๋ฅผ importํ์ฌ ์ฌ์ฉํ ๊ฑฐ์
๋ก๊ทธ์ธ ๋ฒํผ์ ํด๋ฆญํ๋ฉด ๋ก๊ทธ์ธ ํจ์๊ฐ ์คํ๋๋ฉฐ
์ผ๋จ ๊ฐ input ํ๊ทธ์ ๊ณต๋ฐฑ์ด ์๋์ง ๊ฒ์ฌํ๋ค. ๋ง์ฝ์ ์์ผ๋ฉด alert ์ผ๋ก ์๋ฌ๋ฉ์ธ์ง๋ฅผ ์ถ๋ ฅํ๋ฉฐ ๋ฆฌํด
2.์๋ฌ๊ฐ ์์ ๊ฒฝ์ฐ try catch๋ฌธ์ ์ฌ์ฉํ์ฌ ๋ง์์ค๋ค.
์ผ๋จ loading์ด ์์๋๋ฉฐ ํ์ฌ input์ ์
๋ ฅ๋์ด์๋ email๊ณผ password์ ๋ณด๋ฅผ firebase์์ ์ธ์ฆ๊ธฐ๋ฅ์ ํตํด
์ฌ์ฉ์๊ฐ ์๋์ง ๊ฒ์ฌ๋ฅผ ํ๊ณ ์์ผ๋ฉด router๋ฅผ ํตํด์ ๊ธฐ๋ณธ ํ์ด์ง๋ก ์ด๋ํ๋ค.
<script>
import { ref } from "vue";
import { signInWithEmailAndPassword } from "firebase/auth";
import { auth } from "../firebase";
import { useRouter } from "vue-router";
export default {
setup() {
// ๋ณ์ ref(์ด๊ธฐ๊ฐ) usestate ์ ๋์ผ
const email = ref("");
const password = ref("");
const loading = ref(false);
const router = useRouter();
//ํ์๊ฐ์
ํด๋ฆญ ์ ์คํ๋๋ ํจ์
const onLogin = async () => {
if (!email.value || !password.value) {
alert("์ด๋ฉ์ผ, ๋น๋ฐ๋ฒํธ๋ฅผ ๋ชจ๋ ํ์ธํด ์ฃผ์ธ์.");
return;
}
try {
loading.value = true;
const { user } = await signInWithEmailAndPassword(
auth,
email.value,
password.value
);
console.log(user.uid);
router.replace("/"); //๋ค๋ก๊ฐ๊ธฐ ํด๋ฆญํ๋ฉด ๋ก๊ทธ์ธ ํ์ด์ง๋ก ์ด๋๋ชปํ๊ฒํจ
} catch (e) {
switch (e.code) {
case "auth/invalid-email":
alert("์๋ชป๋ ์ด๋ฉ์ผ ํ์์
๋๋ค");
break;
case "auth/wrong-password":
alert("๋น๋ฐ๋ฒํธ๊ฐ ํ๋ฆฝ๋๋ค.");
break;
case "auth/user-not-found":
alert("๋ฑ๋ก๋์ง ์์ ์ด๋ฉ์ผ์
๋๋ค.");
break;
default:
alert(e.message);
break;
}
} finally {
loading.value = false;
}
};
return {
email,
password,
loading,
onLogin,
};
},
};
</script>
๋ง์ฝ์ ์๋ฌ๊ฐ ์์ ๊ฒฝ์ฐ
switch๋ฌธ์ ํ์ฉํ์ฌ ์๋ฌ์ฝ๋์ ๋ง๊ฒ ์ถ๋ ฅ๋๋ ์๋ฌ ํ์์์ ๋ฐ๊ฟ์ค๋ค.
https://firebase.google.com/docs/auth/admin/errors?hl=ko
Admin Authentication API ์ค๋ฅ | Firebase
์๊ฒฌ ๋ณด๋ด๊ธฐ Admin Authentication API ์ค๋ฅ ์ปฌ๋ ์
์ ์ฌ์ฉํด ์ ๋ฆฌํ๊ธฐ ๋ด ํ๊ฒฝ์ค์ ์ ๊ธฐ์ค์ผ๋ก ์ฝํ
์ธ ๋ฅผ ์ ์ฅํ๊ณ ๋ถ๋ฅํ์ธ์. ๋ค์์ Firebase Admin Node.js Authentication API์์ ๋ฐ์ํ๋ ์ค๋ฅ ์ฝ๋์ ์ค๋ช
,
firebase.google.com
๋ผ์ฐํฐ๋ฅผ ์ด์ฉํ์ฌ ์ ์์ ์ผ๋ก ๋ก๊ทธ์ธ๋๋ฉด
๊ธฐ๋ณธ ํ์ด์ง๋ก ์ด๋ํ๊ฒ ํ๋๋ฐ
๋ค๋ก๊ฐ๊ธฐ๋ฅผ ๋๋ฅด๋ฉด loginํ์ด์ง๋ก ์ด๋ํ๋ฉด ๊ณค๋ํ๋๊น
ํ์๊ฐ์
ํ์ด์ง์ ๋ค๋ฅด๊ฒ
push => replace๋ฅผ ์ฌ์ฉํ๋ค.
router.replace("/"); //๋ค๋ก๊ฐ๊ธฐ ํด๋ฆญํ๋ฉด ๋ก๊ทธ์ธ ํ์ด์ง๋ก ์ด๋๋ชปํ๊ฒํจ
์ ์์ ์ผ๋ก ๋ก๊ทธ์ธ๋๋ฉด ์ฝ์์ uid๊ฐ ์ถ๋ ฅ๋จ์ ํ์ธํ๋ค.
resgiter(ํ์๊ฐ์
) ํ์ด์ง๋ ์์ธ์ฒ๋ฆฌ๋ฅผ ์ํด ์์ ํด์ค๋ค.
//ํ์๊ฐ์
ํด๋ฆญ ์ ์คํ๋๋ ํจ์
const onRegister = async () => {
if (!username.value || !email.value || !password.value) {
alert("์ ์ ๋ค์, ์ด๋ฉ์ผ, ๋น๋ฐ๋ฒํธ๋ฅผ ๋ชจ๋ ํ์ธํด ์ฃผ์ธ์.");
return;
}
} catch (e) {
switch (e.code) {
case "auth/invalid-email":
alert("์๋ชป๋ ์ด๋ฉ์ผ ํ์์
๋๋ค");
break;
case "auth/week-password":
alert("๋น๋ฐ๋ฒํธ๊ฐ ๋๋ฌด ์ฌ์์");
break;
case "auth/email-already-in-use":
alert("์ด๋ฏธ ๊ฐ์
๋์ด ์๋ ์ด๋ฉ์ผ์
๋๋ค.");
break;
default:
alert("ํ์๊ฐ์
์คํจ");
break;
}
} finally {
loading.value = false; //๋ก๋ฉ ์ข
๋ฃ
}
};