iT邦幫忙

第 12 屆 iThome 鐵人賽

DAY 24
1

昨天我們提到了Firebase 的Authentication~ 今天就會純coding,帶大家走過一遍完整的登入到登出流程!

前言

今天會比較多coding~ 最主要分為這幾part:

  1. firebaseConfig.js
  2. Login.vue
  3. Logout.vue
  4. forgotPassword.vue
  5. Register.vue
  6. Admin.vue
  7. 最後會回到AppHeader.vue 跟 routes.js去導入這些新的components

整個資料架構可以參考我的~ 也可以自己決定:
https://ithelp.ithome.com.tw/upload/images/20200924/20129730uxiOj1SYIS.jpg


firebaseConfig.js

昨天有稍微提到~ 今天再詳細講過,最主要我們要在這裡設定怎麼跟firebase去做連接~ 之前在開啟專案之後其實有複製過一大堆金鑰甚麼的不知道你們記不記得,就在同一個地方我們要在最後面多export出一個firebaseAuth的功能。

export const db = firebase.firestore();
export const firebaseAuth = firebase.auth();
  • firestore: 我們之前的database位置
  • firebase.auth(): 昨天開好的Authentication 功能

Login.vue

先有個預備流程~ 我們如果要User可以Login,那基本上我們應該會需要他打帳號 + 密碼 -> 再來要拿這組帳號密碼去firebase 找有沒有相同的資料 -> 如果有就可以成功登入,沒有就請他註冊

<template>
  <div class="container m-5">
    <form @submit.prevent="userLogin">
      <h3>登入</h3>

      <div class="form-group">
        <label>郵件地址</label>
        <input
          type="email"
          class="form-control form-control-lg"
          v-model="user.email"
        />
      </div>

      <div class="form-group">
        <label>密碼</label>
        <input
          type="password"
          class="form-control form-control-lg"
          v-model="user.password"
        />
      </div>

      <button type="submit" class="btn btn-dark btn-lg btn-block">登入</button>
      <button class="btn btn-dark btn-lg btn-block">
        <router-link to="/register">
          註冊
        </router-link>
      </button>

      <p class="forgot-password text-right mt-2 mb-4">
        <router-link to="/forgot-password">忘記密碼?</router-link>
      </p>
    </form>
  </div>
</template>

<script>
import { firebaseAuth } from "@/config/firebaseConfig.js";

export default {
  data() {
    return {
      user: {
        email: "",
        password: "",
      },
    };
  },
  methods: {
    userLogin() {
      firebaseAuth
        .signInWithEmailAndPassword(this.user.email, this.user.password)
        .then(() => {
          this.$router.push("/admin");
        })
        .catch((error) => {
          alert(error.message);
        });
    },
  },
};
</script>

HTML的地方不需要太多的解釋,基本上我們都是用v-model的方式綁定user input。

userLogin()的地方你可以看到我們有一個firebaseAuth.,這對應到我們從firebaseConfig.js導入的Auth功能,之後接到 signInWithEmailAndPassword(emial, password),這個就是firebase authenticaiton的功能,可以拿這組帳號密碼到firebase去做驗證~ 成功的話就導入Admin Page,失敗的話就報錯!


Logout.vue

這裡其實就很簡單啦~ 可以甚至不需要有這一頁,只須要有一個funciton告訴firebase我要登出就好了。但我還是加上一頁告知user: 請問你要登出嗎?

<template>
    <div class="container m-5">
        <h3>您好,請問要登出嗎?</h3>
           <p>{{user.displayName}}</p>
           <p>{{user.email}}</p>
        
        <button 
        type="submit" 
        class="btn btn-dark btn-lg btn-block"
        @click="logOut()">
            登出
        </button>
    </div>
</template>

<script>
import { firebaseAuth } from "@/config/firebaseConfig.js";

export default {
  data() {
    return {
      user: null
    };
  },
  created() {
    firebaseAuth.onAuthStateChanged((user) => {
      if (user) {
        this.user = user;
      } else {
        this.user = null;
      }
    });
  },
  methods: {
    logOut() {
      firebaseAuth.signOut().then(() => {
        firebaseAuth.onAuthStateChanged(() => {
          this.$router.push('/login')
        })
      })
    }
  }
};
</script>

這邊有一個很好玩的東西~ 就是我們有{{ user.displayName }},這也是firebase的功能,我們在created時候就去firebase看看我們現在正在操作的user是不是同一個登入過的,如果是的話user = current user的意思。

再來就是我們有兩個firebase authentucation 的功能:

  1. signOut():這...就是登出XD
  2. onAuthStateChange(): 我們登出完之後有一個.then(() => {}) (前天在async有提到),我們登出之後,就代表我們登入的狀態改變成登出了,那如果真的成功登出了就會帶我們回到login頁面。

forgotPassword.vue

當user跟我依樣記憶很差忘記自己密碼怎麼辦?別擔心,firebase可以重新發送驗證信件到已經註冊過的信箱,讓使用者重新輸入新的密碼~ 這邊用到的funciton 叫做 sendPasswordResetEmail(email):

<template>
    <div class="container m-5">
        <form @submit.prevent="forgetPassword">
            <h3>忘記密碼</h3>

            <div class="form-group">
                <label>信箱</label>
                <input type="email" class="form-control form-control-lg" v-model="user.email" />
            </div>

            <button type="submit" class="btn btn-dark btn-lg btn-block">重新設定密碼</button>
        </form>
    </div>
</template>

<script>
import { firebaseAuth } from "@/config/firebaseConfig.js";

export default {
  data() {
    return {
      user: {   
        email: ''
      }
    };
  },
  methods: {
    forgetPassword() {
        firebaseAuth
        .sendPasswordResetEmail(this.user.email)
        .then(() => {
            alert('請查看您的信箱以重設密碼')
            this.user = {   
              email: ''
            }
        }).catch((error) => {
          alert(error)
        })
    }
  }
};
</script>

Register.vue

好的那回到註冊頁面,我們剛剛不論是在登入,登出,還是忘記密碼都是從database裡面去調資料 (還有改變user state),那我們就要有一個方法可以把資料輸進去啦~

<template>
  <div class="container m-5">
    <form @submit.prevent="userRegistration">
      <h3>註冊</h3>

      <div class="form-group">
        <label>名子</label>
        <input
          type="text"
          class="form-control form-control-lg"
          v-model="user.name"
        />
      </div>

      <div class="form-group">
        <label>信箱</label>
        <input
          type="email"
          class="form-control form-control-lg"
          v-model="user.email"
        />
      </div>

      <div class="form-group">
        <label>密碼</label>
        <input
          type="password"
          class="form-control form-control-lg"
          v-model="user.password"
        />
      </div>

      <button type="submit" class="btn btn-dark btn-lg btn-block">
        註冊
      </button>

      <p class="forgot-password text-right">
        已經註冊過了?
        <router-link to="/login">登入</router-link>
      </p>
    </form>
  </div>
</template>

<script>
import { firebaseAuth } from "@/config/firebaseConfig.js";

export default {
  data() {
    return {
      user: {
        name: "",
        email: "",
        password: "",
      },
    };
  },
  methods: {
    userRegistration() {
      firebaseAuth
        .createUserWithEmailAndPassword(this.user.email, this.user.password)
        .then((res) => {
          res.user
            .updateProfile({
              displayName: this.user.name,
            })
            .then(() => {
              this.$router.push("/login");
            });
        })
        .catch((error) => {
          alert(error.message);
        });
    },
  },
};
</script>

這邊我們一樣用v-model來綁定使用者輸入的資料,包含了email, user name, password

再來到script的地方,這邊使用到function 叫做: createUserWithEmailAndPassword(email, password),顧名思義就是....註冊,接下來我們就要去設定profile: updateProfile,把displayName(firebase設定的變數)設成user輸入的名稱。


Admin.vue

基本上你要打甚麼都可以啦~ 這裡就是要成功登入的人才看的到的秘密頁面 lol


AppHeader.vue

在這個NavBar裡面新增login, logout的導覽連結~

<b-nav-item-dropdown text="User" right>
  <b-dropdown-item><router-link to="/login">Login</router-link></b-dropdown-item>
  <b-dropdown-item><router-link to="/register">Register</router-link></b-dropdown-item>
  <b-dropdown-item><router-link to="/logout">Logout</router-link></b-dropdown-item>
</b-nav-item-dropdown>

routes.js

剛剛已經看到許多 <router-link to='....' />,現在就直接在routes.js裡面定義那些代表哪一個component頁面吧~

import Logout from "./components/auth/logout.vue";
import Login from "./components/auth/Login.vue";
import Register from "./components/auth/Register.vue";
import ForgotPassword from './components/auth/forgotPassword.vue';
import AdminPanel from './components/auth/admin.vue';

export default [
  {
    path: "/logout",
    component: Logout,
  },
  {
    path: "/forgot-password",
    component: ForgotPassword,
  },
  {
    path: "/login",
    component: Login,
  },
  {
    path: "/register",
    component: Register,
  },
  {
    path: "/admin",
    component: AdminPanel,
  }
];

後記

就跟你說是純coding的一天~ 我希望不要讓你們話太多時間設計頁面所以把coding貼了上來,但如果可以的話script的地方要自己寫比較好喔,自己打上去才有印象firebase authentucation提供的function 有甚麼!

大家繼續努力~


上一篇
【D23 - 用Vue實作網頁】Firebase說他還可以幫忙Authenticate?
下一篇
【D25 - Vuex】給你一個方便的儲藏室!!
系列文
到底要怎麼開始開發網站? --- 從入門到使用Vue, Firebase製作老闆交代的網站30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言