如何在Quasar Vue.js应用程序中使用Firebase进行谷歌认证

387 阅读10分钟

在Quasar Vue.js应用程序中使用Firebase进行谷歌认证

在一个应用程序中,提供一个特定的授权流程将在保证安全的前提下减轻对用户的认证。开放授权(OAuth)提供了这样一个标准,而不必处理用户的敏感数据,如他们的密码。Firebase以最连贯的方式用google auth provider实现了OAth 2.0。

前提条件

要跟上这个教程,你需要。

  • 有[Vue.js]的基本知识。
  • [Node.js]10.x或更新版本,不包括13和15。这些版本没有经过Quasar的测试。
  • [NPM]5.10或更新版本/Yarn 1.2或更新版本。

设置Quasar Vuejs应用程序

在设置应用程序之前,让我们检查一下Quasar CLI是否在你的电脑上全局安装。使用终端运行。

quasar -v

如果出现命令未找到的错误,请运行以下命令来安装它。

npm install -g @quasar/cli

如果你使用的是yarn,请运行。

yarn global add @quasar/cli

用Quasar创建一个quasar-firebase应用程序

创建一个quasar应用程序是一个简单的步骤。你要自己来做。

创建我们的应用程序组件

导航到src 文件夹,打开Index.vue ,删除图像标签,看起来像下面这样。

<img alt="Quasar logo" src="~assets/quasar-logo-full.svg">

Index.vue 文件重命名为Auth.vue ,在pages 文件夹内创建另一个名为Home.vue 的文件。然后在模板标签内添加一个div标签<div> ,代码如下。

<template>
  <q-page class="flex q-pa-md">
      Welcome Home
    <q-space />
    <div>
      <q-btn
        class="flex flex-center q-px-lg q-py-sm q-mb-md"
        size="md"
        label="Logout"
        @click="logout"
        color="primary"
      />
    </div>
  </q-page>
</template>

<Script> 标签内添加下面的代码。

export default {
name: "Home",
  data () {
  return {}
  },
  methods: {
    logout() {
      console.log('logged out')
    }
  }
}

现在,导航到router 文件夹,打开routes.js ,并编辑默认的路由属性,使其与各个组件相匹配,如下所示。

我们将创建组件作为我们的下一步。

const routes = [
  {
      path: '/',
      component: () => import('layouts/MainLayout.vue'),
      children: [
          { path: '/', component: () => import('src/pages/Auth.vue') },
          { path: '/home', component: () => import('src/pages/Home.vue'), meta: {requiresAuth: true} }
      ]
  },
  // Always leave this as the last one,
  // but you can also remove it
  {
    path: '/:catchAll(.*)*',
    component: () => import('pages/Error404.vue')
  }
]
export default routes

根据上面的路由,/ 路径是允许所有人使用的,但/home 只允许登录用户使用。

requiresAuth 元属性被设置为true ,它负责守卫路由。

在向我们的应用程序添加firebase之后,这将得到很好的证明。

签到/登录组件

我们将创建一个签到/签到组件。导航到components 文件夹,创建一个新的文件AuthComponent.vue 并粘贴下面的代码。

<template>
  <div>
    <template v-if="tab === 'register'">
      <div class="text-center q-mb-lg">Sign up with</div>
    </template>
    <template v-else>
      <div class="text-center q-mb-lg">Sign in with</div>
    </template>
    <div class="flex flex-center">
      <q-btn class="flex flex-center q-px-lg q-py-sm q-mb-md" color="primary" size="md"  label="Google" 
        @click="google" 
      />
    </div>
    <template v-if="tab === 'register'">
      <p class="text-center">Sign up with credentials</p>
    </template>
    <template v-else>
      <p class="text-center">Sign in with credentials</p>
    </template>

    <q-form @submit="submitForm">
      <q-input outlined class="q-mb-md" type="email" label="Email" v-model="formData.email" />
      <q-input outlined class="q-mb-md" type="password" label="Password" v-model="formData.password" />
      <div class="row">
        <q-space />
        <q-btn type="submit" color="primary" :label="tab" />
      </div>
    </q-form>
    <div class="text-center q-my-md">
      <q-btn flat label="Forgot Password?" color="green" class="text-capitalize rounded-borders"
        v-if="tab !== 'register'" @click="forgotPassword" />
    </div>
    <q-dialog v-model="resetPwdDialog">
      <ForgotPassword />
    </q-dialog>
  </div>
</template>

这是一个显示签到和签到的AuthComponent的标签。对于<script> 标签粘贴下面的代码。

import ForgotPassword from "./ForgotPassword.vue";
export default {
  name: "AuthComponent",
  props: ['tab'],
  components: { ForgotPassword },
  data (){
    return {
      formData: {
        email: '',
        password: ''
      },
      resetPwdDialog: false
    }
  },
  methods: {
    submitForm () {
      if (this.tab === 'login') {
         this.signInExistingUser(this.formData.email, this.formData.password)
      } else {
        this.createUser(this.formData.email, this.formData.password)
      }
    },
    google () {
      console.log('google login & signup')
    },
     signInExistingUser (email, password) {
      console.log(email, password)
    },
    createUser(email, password) {
      console.log(email, password)
    },
    forgotPassword () {
      this.resetPwdDialog = true
    }
  }
}

在上面的代码中,我们导入了我们接下来要创建的ForgotPassword 组件。数据函数有表单输入数据。

方法google() 将处理Firebase google授权,而forgotPassword() 旁边的resetPwdDialog 数据属性将显示密码重设的对话框。

创建忘记密码组件

在接下来的阶段,我们将创建ForgotPassword 组件,在components 文件夹中创建ForgotPassword.vue 文件,并在其中粘贴以下代码。

<template>
  <div class="flex flex-center">
    <q-card style="width: 500px; max-width: 40vw;">
      <q-card-section class="row items-center q-pb-none">
        <div class="text-h6">
          Reset Password
        </div>
        <q-space />
        <q-btn icon="close" flat round dense v-close-popup />
      </q-card-section>
      <q-card-section class="q-pt-md">
        <q-form ref="resetPasswordForm">
          <q-input
            type="email"
            v-model="form.email"
            label="Email *"
            lazy-rules
            :rules="[val => (val && val.length > 0) || 'Please type your email']"
          />
        </q-form>
        <q-card-actions align="right">
          <div class="row q-mt-xs">
            <q-btn
              class="q-pl-md q-pr-md q-mr-md text-capitalize rounded-borders"
              label="Submit"
              color="primary"
              @click="resetPassword"
            />
          </div>
        </q-card-actions>
      </q-card-section>
    </q-card>
  </div>
</template>

<script> 标签中粘贴下面的代码。

export default {
  name: "ForgotPassword",
  data (){
    return {
      form: {
        email: ''
      }
    }
  },
  methods: {
    resetPassword () {
      // firebase reset password
    }
  }
}

这个组件被导入到AuthComponent.vue ,其中有一个用于重设密码的表单。

现在,一切都还没有正确显示。导航到pages 文件夹,打开Auth.vue ,粘贴下面的代码。

<template>
  <q-page class="flex q-pa-md">
    <q-card class="full-width">
      <q-tabs
        v-model="tab"
        dense
        class="text-grey"
        active-color="primary"
        indicator-color="primary"
        align="justify"
        narrow-indicator
      >
        <q-tab name="login" label="Login" />
        <q-tab name="register" label="Register" />
      </q-tabs>


      <q-tab-panels v-model="tab" animated>
        <q-tab-panel name="login">
          <AuthComponent :tab="tab" />
        </q-tab-panel>

        <q-tab-panel name="register">
          <AuthComponent :tab="tab"/>
        </q-tab-panel>
      </q-tab-panels>
    </q-card>
  </q-page>
</template>

上面的AuthComponent 被导入到pages/Auth.vue ,其中有注册和登录标签的道具。在<script> 标签中粘贴下面的代码。

import AuthComponent from "components/AuthComponent";
export default {
  components: { AuthComponent },
  data () {
    return {
      tab: 'login'
    }
  }
}

将Firebase添加到我们的应用程序中

要将Firebase添加到我们的应用程序中,请确保以下操作是正确的。

  1. 访问[firebase控制台]。
  2. 点击Add Project ,创建一个Firebase项目来连接到我们的应用程序。将其命名为quasar-google-auth ,并点击Continue
  3. 禁用这个项目的Google Analytics,然后点击Continue 来创建我们的项目。
  4. 项目准备好后,点击Continue 。它将带你到项目概览。点击web 图标,注册一个应用程序名称并将其命名为quasar-firebase-googleauth ,然后点击Register App
  5. 你会被带到Step 2 - Add Firebase SDK ,并复制整个脚本。

我们要安装firebase,并创建一个引导文件,在我们的应用程序运行前初始化firebase。

回到我们的项目,打开终端,并运行以下命令。

yarn add firebase
quasar new boot firebase

导航到quasar.conf.js 文件并搜索boot 。它应该是一个空数组。在其中添加firebase.js 启动文件,如下所示。

boot: ['firebase'],

导航到boot 文件夹并打开firebase.js 文件。

替换firebase.js 文件中的现有代码,使其与下面的代码相似,然后粘贴你在上一步复制的Firebase SDK脚本。

import firebase from "firebase";

const firebaseConfig = {
    apiKey: "xxxxxxxxxxx",
    authDomain: "xxxxxxxxxx",
    projectId: "xxxxxxxxxx",
    storageBucket: "xxxxxxxx",
    messagingSenderId: "xxxxxxxxx",
    appId: "xxxxxxx"
  };
  firebase.initializeApp(firebaseConfig);

export default firebase

路由的访问控制

当用户需要访问需要授权的路由时,我们要禁止对这些路由的访问。这很简单。导航到routes 文件夹,打开index.js 文件。

在文件的顶部导入Firebase,就像我们在firebase.js 启动文件中做的那样。

完成后,在return Router 行的上方添加以下代码。

  Router.beforeEach(async (to, from, next) => {
    const auth = to.meta.requiresAuth
    if (auth && !await firebase.getCurrentUser()) {
      next('/');
    } else {
      next();
    }
  })

现在,如果currentUser为空或未定义,我们应该将用户重定向到auth路径(/)。但我们如何获得currentUser呢?我们不能使用firebase.auth().currentUser ,因为在页面刷新时,该属性在触发requiresAuth 守护之前还没有被设置。

我们必须以某种方式使用onAuthStateChanged 的回调。我们必须在初始化firebase应用后给firebase对象添加一个方法。这个方法被添加到firebase.js 启动文件中。编辑firebase引导文件,使其类似于下面的代码。

const firebaseConfig = {
    apiKey: "xxxxxxxxxxx",
    authDomain: "xxxxxxxxxx",
    projectId: "xxxxxxxxxx",
    storageBucket: "xxxxxxxx",
    messagingSenderId: "xxxxxxxxx",
    appId: "xxxxxxx"
  };
  firebase.initializeApp(firebaseConfig);

  firebase.getCurrentUser = () => {
    return new Promise((resolve, reject) => {
      const unsubscribe = firebase.auth().onAuthStateChanged(user => {
        unsubscribe();
        resolve(user);
      }, reject);
    })
  };

firebase.getCurrentUser 将返回一个Promise,一旦设置了currentUser,它就会被解析。 ,将立即用null或用户对象(如果已登录)触发回调。然后我们取消订阅,不再监听进一步的变化。onAuthStateChanged

激活签到方法

我们需要激活firebase提供的登录方法,我们将激活googleEmail/Password 提供者。回到我们复制了firebase SDK脚本的firebase控制台。点击Continue to console ,它将带你到项目概览。

在左边的侧边栏点击Authentication ,然后点击Set up sign-in method 。下面的图片显示了登录提供者的位置。

Sign-in methods

点击Email/PasswordGoogle 提供者来激活它们,因为默认情况下它们是被禁用的,如上图所示。

对于电子邮件/密码,点击第一个切换按钮,不要启用passwordless sign-in 选项。

Enable Email/Password Provider

至于谷歌,供应商确保填写你的Project support email ,最好是你的电子邮件地址。

Enable Google Provider

一旦完成,我们就可以开始向我们的视图添加功能。

添加与谷歌供应商的登录功能

导航到AuthComponent.vue 文件。让我们导入firebase。如下面所示。

import firebase from "firebase";

google() 方法中,我们创建一个提供者变量,包含用来用google登录用户的GoogleAuthProvider 。编辑google() 方法,使其类似于下面的代码。

google () {
  const provider = new firebase.auth.GoogleAuthProvider()
  firebase.auth().signInWithPopup(provider)
  .then(result => {
    console.log('result', result)
    this.$q.notify({message: 'Sign In Success.'})
    this.$router.push('/home')
  })
  .catch(error => console.log('error',error))
},

当你点击Google 签到按钮时,这应该能让你签到。

在点击按钮之前,导航到quasar.conf.js 文件,搜索plugins ,这应该是一个空数组。添加notify插件,这将在认证完成后提供通知。该插件应作为一个字符串添加。如下面所示。

plugins: [ 'Notify' ]

添加完插件后,让我们完成另一个提供者(Email/Password),当用户不想用Google登录时,这个提供者就会很方便。

添加电子邮件/密码提供者功能

打开AuthComponent.vue 文件,在createUser() 方法中,这个方法将被用来创建一个新的用户到数据库中,为这个方法粘贴以下代码。

createUser(email, password) {
  firebase.auth().createUserWithEmailAndPassword(email, password)
    .then(auth => {
      this.$q.notify({message: 'Sign In Success.'})
      this.$router.push('/home')
    })
    .catch(error => {console.log(error)
    })
},

当一个用户被创建时,它会将用户重定向到主页,在页面的底部有一个Sign In Success 的通知。

接下来,我们要创建一个signInExistingUser() 方法,这个方法签入已经注册的用户。为该方法粘贴以下代码。

signInExistingUser (email, password) {
  firebase.auth().signInWithEmailAndPassword(email, password)
    .then((userCredential) => {
      this.$q.notify({message: 'Sign In Success.'})
      this.$router.push('/home')
    })
    .catch(error => { console.log(error)})
},

到现在,你可以用谷歌或你的电子邮件/密码登录。如果成功,你会被重定向到主页,包含一个欢迎信息和一个注销按钮。

如果你在本地工作,遇到了登录问题,去项目中的firebase控制台,点击Authentication ,然后是Sign-in method ,在Sign-in providers ,你会看到Authorized domains 。点击Add domain ,然后添加localhost 。当你的应用程序被托管时,你可以添加自定义域名。

Customize Domain

接下来,我们要添加注销功能,一旦用户登录,他们应该能够注销应用程序。

添加注销功能

在这个阶段,如果你做得很正确,你就能登录并被重定向到主页,在那里你会看到一个注销按钮。

要添加注销功能,导航到Pages 文件夹,打开Home.vue 文件,在<script> 的开头标记import firebase from "firebase" ,就像在AuthComponent.vue 文件中一样

中的方法logout ,替换其代码,使之类似于下面的代码。

logout() {
  firebase.auth().signOut()
  this.$router.push('/')
    .then(() => {
    this.$q.notify({message: 'Sign Out Success.'})
  })
  .catch(error =>  console.log('error',error))
}  

这个方法将用户重定向到auth路线,并通知他们已经被签出。

添加忘记密码的功能

如果用户忘记了他们的密码,他们应该能够重新设置一个新的密码并与我们的应用程序互动。让我们来处理这个问题。

导航到ForgotPassword.vue 文件,它有一个我们之前添加的重置密码的方法。这个方法将帮助我们发送电子邮件来重设密码。

以下是该方法的代码。

resetPassword () {
  firebase.auth().sendPasswordResetEmail(this.form.email)
    .then(() => {
      this.form = {}
      this.$q.notify({message: 'Check you email and reset your password.'})
    })
    .catch(error => console.log(error))
}

如果用户输入了他们的电子邮件,并且该电子邮件存在于数据库中,那么将向用户发送一封电子邮件来重置密码。如果电子邮件不存在,就会产生一个错误。

访问用户信息

当一个用户登录后,我们可以访问他们的信息,并在欢迎词中显示。导航到Home.vue 文件。让我们做一些修改。

<template> 标签中,编辑欢迎信息,使其类似于下面这个。

Welcome Home {{ user }} {{ email }}

<script> 标签中添加两个数据属性,以保存已成功登录的用户的姓名和电子邮件。编辑数据功能,使之与下面相似。

data () {
  return {
    user: '',
    email: ''
  }
},

现在,让我们添加一个生命周期钩子,当用户被重定向到主页时,我们访问用户的信息并将其显示给他们。在<script> 标签内,就在data函数之后,粘贴下面的钩子created()

data () { return { ... }},
created() {
  firebase.auth().onAuthStateChanged((auth) => {
    if (auth) {
      this.user = auth.displayName
      this.email = auth.email
    } else {
      console.log('user name is null')
    }
  })
},
methods: {...}

当用户用谷歌或电子邮件/密码登录时,它将在他们的名字和电子邮件旁边显示欢迎信息,如果用户名为空,则显示他们的电子邮件。

总结

Firebase通过OAuth 2.0等标准实现谷歌认证,已经被证明是为应用程序提供认证的最佳解决方案之一。

无论是大型还是小型的应用程序,让第三方应用程序处理你的用户的敏感信息是可靠的,缩短了应用程序的开发时间,最重要的是,它可以整合其他社交媒体的认证,如Facebook、Twitter和GitHub。

这使得新用户可以轻松地登录到你的应用程序。导致更多的用户访问你的应用程序提供的服务。