> 웹 프론트엔드 > JS 튜토리얼 > Firebase Vue JS #STEP에 로그인/등록(로그인)

Firebase Vue JS #STEP에 로그인/등록(로그인)

Barbara Streisand
풀어 주다: 2024-10-26 05:37:30
원래의
1043명이 탐색했습니다.

프로젝트 로그인 경로를 생성해 보겠습니다. 아래 구조에 중점을 두겠습니다.

.
├── 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에 액세스하면 아래와 비슷한 화면이 표시됩니다.

Login/cadastro com firebase   Vue JS #PASSO  (login)

제 글을 끝까지 읽어주셔서 감사합니다. 제작에 어려움을 겪고 있거나 개발을 시작하는 많은 분들께 도움이 되었으면 좋겠습니다. 문제가 있으면 언제든지 의견을 보내주세요. 가능할 때마다 문제를 분석하여 도움을 드리겠습니다.

Login/cadastro com firebase   Vue JS #PASSO  (login)

위 내용은 Firebase Vue JS #STEP에 로그인/등록(로그인)의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

원천:dev.to
본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
저자별 최신 기사
인기 튜토리얼
더>
최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿