我們來建立專案登入路由,以下將重點放在這個結構。
. ├── src │ └── router │ └── index.js
在index.js檔案中我們將加入以下內容:
import { createRouter, createWebHistory } from 'vue-router' import { getAuth, onAuthStateChanged } from 'firebase/auth' import Login from '@/module/login/view/login.vue' import Register from '@/module/register/view/register.vue' import Home from '@/module/home/view/home.vue' const router = createRouter({ history: createWebHistory(), routes: [ { path: '/', name: 'home', component: Home, meta: { requiresAuth: true } }, { path: '/login', name: 'Login', component: Login }, { path: '/cadastro', name: 'Register', component: Register } ] }) const getCurrentUser = () => { return new Promise((resolve, reject) => { const removeListener = onAuthStateChanged( getAuth(), (user) => { removeListener() resolve(user) }, reject ) }) } router.beforeEach(async (to, from, next) => { const currentUser = await getCurrentUser() if (to.matched.some((record) => record.meta.requiresAuth)) { if (currentUser) { next() } else { alert("Você não tem acesso a essa página, por favor, autentique-e!") next('/login') } } else if ( currentUser && (to.path === '/login' || to.path === '/cadastro' ) { next('/') } else { next() } }) export default router
請注意,現在,我們的路由檔案更加完整,我們新增了 firebase/auth 導入,以便我們可以建立驗證,以便使用者在未經身份驗證的情況下無法存取螢幕。
簡而言之,const 路由器下的這部分在每次在受保護的路線上導航之前檢查使用者身份驗證。 getCurrentUser 函數使用 onAuthStateChanged 方法來監視身份驗證並傳回經過驗證的使用者的承諾。在router.beforeEach中,它檢查路由是否需要身份驗證(由meta.requiresAuth指示)。如果路由受到保護且使用者經過身份驗證,則允許存取(next())。如果使用者未通過身份驗證,則會顯示警報並重定向到 /login。如果使用者已經通過身份驗證並嘗試存取 /login 或 /cadastro,則會將其重定向到主頁 (/),此外,我們添加了一條到 Home 的路由和另一個到 /login 的路由。
關於主頁,我不會創建該文件,我只是將其放在那裡,以便您可以看到它如何檢查用戶是否可以訪問。
現在,讓我們繼續創建實際的註冊元件、它的函數和調用,所以讓我們專注於這個結構。
. ├── src │ └── module │ └── login | └── component | └── formlogin.vue | └── controller | └── loginController.js | └── view | └── login.vue
formLogin.vue 檔案。
<template> <div class="d-flex justify-center align-center fill-height"> <v-card class="mx-auto px-6 py-8" max-width="400" min-width="300"> <v-form :disabled="controller.loading.value" :readonly="controller.loading.value"> <h1 class="text-center mb-3">Entrar</h1> <v-text-field class="mb-2" label="E-mail" variant="underlined" clearable :rules="[controller.regras.required, controller.regras.validEmail]" v-model="controller.email.value" ></v-text-field> <v-text-field label="Senha" placeholder="Informe sua senha" variant="underlined" clearable @click:append-inner="controller.showPassword.value = !controller.showPassword.value" :append-inner-icon="controller.showPassword.value ? 'mdi-eye' : 'mdi-eye-off'" :type="controller.showPassword.value ? 'text' : 'password'" :rules="[ controller.regras.required, (v) => (v && v.length >= 6) || 'A senha deve ter no mínimo 6 caracteres' ]" v-model="controller.password.value" ></v-text-field> <p v-if="controller.errMsg.value" class="text-red text-center"> {{ controller.errMsg.value }} </p> <br /> <v-btn color="#5865f2" size="large" type="submit" variant="elevated" block :loading="controller.loading.value" :disabled=" !controller.password.value || controller.password.value.length < 6 || controller.loading.value " @click="controller.login" > Entrar </v-btn> <br /> <v-divider class="mx-10"></v-divider> <div class="d-flex justify-center mt-3"> <button @click="controller.signInWithGoogle"> <v-avatar :image="logoGoogle"></v-avatar> </button> </div> <p class="text-center mt-5"> Ainda não possui uma conta? <a href="/cadastro">Cadastre-se</a> </p> </v-form> </v-card> </div> </template> <script setup> import logoGoogle from '../../../assets/images/imagem_logo_google.png' const { controller } = defineProps({ controller: { type: Object, required: true } }) </script>
loginController.js 檔案。
import { ref } from 'vue' import { getAuth, signInWithEmailAndPassword, GoogleAuthProvider, signInWithPopup, } from 'firebase/auth' import { useRouter } from 'vue-router' const loginController = () => { const email = ref('') const password = ref('') const errMsg = ref('') const loading = ref(false) const showPassword = ref(false) const regras = { required: (v) => !!v || 'Obrigatório', validEmail: (v) => { if (v.length > 0) { const pattern = /^(([^<>()[\]\.,;:\s@"]+(\.[^<>()[\]\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/ return pattern.test(v) || 'E-mail inválido' } return true }, const router = useRouter() const auth = getAuth() // Essa função é responsável por realizar o login com o firebase apenas informando o e-mail e senha const login = async () => { try { loading.value = true errMsg.value = '' await signInWithEmailAndPassword(auth, email.value, password.value) router.push('/') } catch (error) { // Note que aqui, temos um switch/case com os possíveis erros que o firebase retorna, essa variável `errMsg` está lá no `formLogin.vue` para que o usuário possa ver o erro que está retornando switch (error.code) { case 'auth/invalid-email': errMsg.value = 'E-mail inválido!' break case 'auth/user-not-found': errMsg.value = 'Usuário não encontrado!' break case 'auth/wrong-password': errMsg.value = 'Senha incorreta!' break default: errMsg.value = 'E-mail ou senha incorretos!' break } } finally { loading.value = false } } // Essa função é responsável por realizar o login com o firebase utilizando o provedor Google const signInWithGoogle = async () => { try { loading.value = true const provider = new GoogleAuthProvider() await signInWithPopup(auth, provider) router.push('/') } catch (error) { alert(error) } finally { loading.value = false } } return { email, password, errMsg, loading, showPassword, regras, login, signInWithGoogle } } export { loginController }
Login.vue 檔案。
<template> <form-login :controller="controller" /> </template> <script setup> import { loginController } from '../controller/loginController' import FormLogin from '../component/formLogin.vue' const controller = loginController() </script>
這樣,我們就完成了註冊和登入畫面,在這篇文章中,我們將路由新增至/login,我們將驗證新增至router/index.js,以便使用者只有透過身分驗證才能存取主頁,並且我們建立登入元件,在一切結束時,存取/login 您應該看到類似於下面的畫面:
感謝您閱讀我的文章直到最後,我希望這可以幫助許多遇到困難或開始發展的人。您有任何問題,請隨時發表評論,只要有可能,我會分析您的問題並盡力幫助您。
以上是使用 firebase Vue JS 登入/註冊#STEP(登入)的詳細內容。更多資訊請關注PHP中文網其他相關文章!