前幾天完成了關於發送認證信的各種細節,但認證碼發出去後,使用者還是需要回到系統認證才能綁定。先前有提過讓使用者手動輸入認證實在不友善,今天就來著手改善這步驟吧~
常見的認證方法有以下兩種:
以驗證碼小幫手來說,第二種方法可以讓使用者快速認證,但同時實作第一種方法則可以增加更多彈性
建立一個新的 Google App Script 專案 User Validation
,並且引入 ReadMail
& ReplyMessage
專案做為資料庫使用,新增 app.gs 內容如下:
function doPost(e) {
var message = 'fail';
const input = JSON.parse(e.postData.contents);
if (input.code && (input.token || input.email)) {
const userId = input.token || getUserIdByEmail(input.email);
if ((userId.length !== 0) && ReplyMessage.tagVerificationCode(input.code, userId)) {
message = 'success';
ReplyMessage.changeRichMenuAfterBindSuccess(userId);
}
}
return ContentService.createTextOutput(JSON.stringify({message})).setMimeType(ContentService.MimeType.JSON);
}
function getUserIdByEmail(email) {
const sheet = ReadMail.connectToSheet('users');
const searchResult = ReadMail.searchColumnValue(sheet, 'email', email);
if (searchResult !== -1) {
const targetRowIndex = searchResult+2;
const targetRowRange = sheet.getRange(targetRowIndex, 1, 1, 1);
return targetRowRange.getValue();
}
return "";
}
因為大部分都是之前就寫好的功能重複使用,所以很快就能完成~接著別忘了儲存並部署為網頁應用程式。
用 vue router 新增一個 validate page
(liff.isLoggedIn() && liff.isInClient())
則檢查是否帶有認證碼 query string
User Validation
進行認證User Validation
進行認證User Validation
進行認證export const validateCodePost = (code, token, email) => {
const targetUrl = "YOUR_USER_VALIDATION_URL";
let data = JSON.stringify({code, token, email});
return axios.post(targetUrl, data, {
headers: { 'content-type': 'application/x-www-form-urlencoded' }
}).then(response => {
if (response) {
return response;
} else {
return Promise.reject();
}
}).catch(error => {
console.log('error', error);
});
};
<script setup>
import {onMounted, ref} from 'vue'
import {validateCodePost} from '/src/service/api'
import * as yup from 'yup';
import { useRoute } from 'vue-router'
const route = useRoute()
const validationCode = ref("");
const userToken = ref("");
const inputEmail = ref("");
const result = ref("");
const showCode = ref(false);
const showMail = ref(false);
const onSubmit = ref(false);
const closeLiff = () => {
liff.closeWindow();
}
const mailSchema = yup.string().email().required();
const submit = async () => {
result.value = "";
onSubmit.value = true;
if (validationCode.value.length === 0) {
onSubmit.value = false;
alert('請輸入認證碼');
return;
}
let res = null;
if (userToken.value.length === 0) {
const isMailValid = await mailSchema.isValid(inputEmail.value);
if (isMailValid) {
res = await validateCodePost(validationCode.value, null, inputEmail.value)
} else {
alert('請輸入有效的信箱地址');
}
} else {
res = await validateCodePost(validationCode.value, userToken.value, null)
}
result.value = (res && res.data.message) || '';
onSubmit.value = false;
}
onMounted(() => {
validationCode.value = route.query.code || '';
showCode.value = validationCode.value.length <= 0;
liff.init({
liffId: 'YOUR_LIFF_ID'
}).then(() => {
if (liff.isLoggedIn() && liff.isInClient()) {
const user = liff.getDecodedIDToken();
userToken.value = user && user.sub;
if (!showCode.value && userToken.value.length > 0) {
submit();
} else {
showMail.value = userToken.value.length <= 0
}
} else {
showMail.value = true;
}
}).catch((err) => {
console.log(err);
showCode.value = true;
showMail.value = true;
});
});
</script>
<template>
<p v-if="showCode" v-show="!onSubmit">認證碼:<input type="email" v-model="validationCode" placeholder="請輸入認證碼"></p>
<p v-if="showMail" v-show="!onSubmit">收到認證碼的信箱:<input type="email" v-model="inputEmail" placeholder="請輸入收到認證碼的信箱"></p>
<button v-if="showCode || showMail" v-show="!onSubmit" type="button" class="btn" @click="submit()" :disabled="onSubmit">送出</button>
<p v-show="onSubmit">認證中,請稍候...</p>
<template v-if="result.length > 0">
<p>{{(result === 'success') ? '認證成功' : '認證失敗'}}</p>
<button type="button" class="btn" @click="closeLiff">關閉</button>
</template>
</template>
npm run build
然後將靜態檔案部署到 Github Pages
因為需要多一個 /validate 的 uri,比較笨但快的做法是在 dist 資料夾底下新建一個 validate 資料夾,並把 dist 資料夾底下的 index.html 拷貝一份到 validate 資料夾底下
將發給使用者認證信的內容修改如下:
var content = `${input.name} 您好,您的身份認證碼為: ${verificationCode},時效為10分鐘。也可點擊此連結進行認證:{YOUR_LIFF_APP_URL}/validate?code=${verificationCode}`;
這樣一來使用者用手機點擊連結就可以直接開啟 Line LIFF APP 綁定認證成功~就算用其他的瀏覽器開啟,我們也能讓使用者手動輸入認證碼/信箱進行認證。
明天就是最後一天了~雖然還有很多能改善的東西,但總歸是告一段落了。