iT邦幫忙

2021 iThome 鐵人賽

DAY 27
0
自我挑戰組

從無到有打造驗證碼共享的 Line 機器人系列 第 27

用 Line LIFF APP 實現信箱驗證綁定功能(4) - 表單驗證電子郵件地址

前幾天完成了一個簡單發送認證碼的 LIFF APP,其實還有很多可以優化的地方,像是在送出 Request 前,需要先檢查使用者輸入的是否為有效的電子郵件地址,以及提供過一段時間後重新發送的功能。

判斷電子郵件地址是否合法

要判斷一個電子郵件地址是否合法,必須要先知道電子郵件地址是由三個部分組成的 {local}@{domain}

  • local:
    • 最多64個字元
    • 通用接受 A-Z, a-z, 0-9, 但大寫字母在某些郵件伺服器可能被拒絕,或者一律視為小寫
    • 接受 . 但不能出現在首尾,也不能連續出現(若在引號內則不受限制)
    • 接受大部分的 ASCII Graphic Char,但實際能否使用還是要看郵件伺服器的限制
    • 在某些郵件伺服器 +- 後面的字元可忽略,也就是說只要 +- 前面的字元相同,便有可能指向同一個收件地址
  • @: 分隔 local & domain
  • domain:
    • 最多255個字元
    • 必須符合嚴格的主機域名規則:一個以點分隔的DNS標籤序列,每個標籤被限定為長度不超過63個字元
    • 通用接受 A-Z, a-z, 0-9, -,其中 - 不能出現在首尾,且頂級域名不可全部由數字組成。

以上是大略統整的規則,更詳細的規則可參考 RFC 5322 (3.2.3 & 3.4.1), RFC 5321RFC 3696,網路上也有很多整理好的 RFC 簡易原則文章。

看完以上這段,就可以發現如果要重新打造一個精準驗證電子郵件地址是否合法的判斷式,是非常複雜且耗時的一件事,為了不重複造輪子,這邊還是使用套件進行驗證吧~

使用套件 - yup

yup 是一個 JavaScript 的內容驗證套件,有不少套件或框架已經在使用它。

Yup is a JavaScript schema builder for value parsing and validation. Define a schema, transform a value to match, validate the shape of an existing value, or both. Yup schema are extremely expressive and allow modeling complex, interdependent validations, or value transformations.

Yup's API is heavily inspired by Joi, but leaner and built with client-side validation as its primary use-case. Yup separates the parsing and validating functions into separate steps. cast() transforms data while validate checks that the input is the correct shape. Each can be performed together (such as HTML form validation) or seperately (such as deserializing trusted data from APIs).

要使用就必須先在我們的 Vue Project 安裝

npm install -S yup

修改 BindMailForm.vue

因為我們先前已經把表單處理的邏輯都拆開放到 BindMailForm.vue,所以只要修改這個檔案即可。修改重點在送出表單前,先檢查郵件地址是否合法。

<script setup>
import {onMounted, ref, defineEmits} from 'vue'
import {sendValidationCodePost} from '/src/service/api'
// import yup
import * as yup from 'yup';

const userName = ref("");
const userToken = ref("");
const userEmail = ref("");
const inputEmail = ref("");

const emit = defineEmits(['nextStep'])

// define mail validate schema
const mailSchema = yup.string().email().required();
const submit = async (mail) => {
  // validate mail before send
  const isMailValid = await mailSchema.isValid(mail);
  if (isMailValid) {
    sendValidationCodePost(userName.value, mail, userToken.value)
        .then((res) => {
          console.log("res: ", res);
          const result = res.data.message;
          emit('nextStep', result);
        })
        .catch((err) => {
          console.log("err: ", err);
        });
  } else {
    alert('請輸入有效的信箱地址');
  }
}

onMounted(() => {
  liff.ready.then(() => {
    const user = liff.getDecodedIDToken();
    userName.value = user && user.name;
    userToken.value = user && user.sub;
    userEmail.value = user && user.email;
  })
})
</script>

<template>
  <template v-if="userEmail">
    <p>將發送身份認證碼到 {{ userEmail }}</p>
    <button type="button" class="btn" @click="submit(userEmail)">確定</button>
  </template>

  <template v-else>
    <p>發送身份認證碼到 <input type="email" v-model="inputEmail" placeholder="請輸入 Email"></p>
    <button type="button" class="btn" @click="submit(inputEmail)">確定</button>
  </template>
</template>

一樣儲存後 npm run build 產生靜態檔案,並上傳到 Github Page,就可以在驗證碼小幫手檢驗成果了~


上一篇
用 Line LIFF APP 實現信箱驗證綁定功能(3) - 修改流程實現認證時效檢驗
下一篇
防止使用者頻繁送出 Request & 倒數計時重新發送認證碼
系列文
從無到有打造驗證碼共享的 Line 機器人30

尚未有邦友留言

立即登入留言