Apps Script用Sheet生成動態網頁(13): 會員登入頁面(LocalStorage)

在先前的會員登入頁面施作中,我們使用?參數作為登入資料的傳遞方式,但是以這種方式難以維護登入狀態,使用者一但重新進入網站,或是開新分頁,就會發現登入狀態消失了,在使用者體驗上十分不好。然而,Apps Script中又不提供傳統紀錄登入Cookie的方式。因此,我們只好求援於HTML5的Local Storage,協助我們儲存登入資訊。

在前一篇文Apps Script用Sheet生成動態網頁(12): 使用LocalStorage紀錄資料中,我們已經學會Local Storage的基本用法,這裡就是要將它應用在登入頁面中。

在登入頁面中我們提供一個表單供使用者輸入帳號、密碼,使用者按下登入按鈕後,會從後端取得登入的token然後透過連結的?參數傳遞給首頁,因此我們要改動紀錄用戶登入資料的部份。

1. 儲存登入資訊

先開啟上次的登入頁面,在onCompleted()加上一行儲存到Local Storage的指令

localStorage.setItem('user-token', response.token);

接著,因為已經用Local Storage儲存登入資料,所以調整回到首頁的URL,整個onCompleted就會改成下面這樣

function onCompleted(response, form) {
form.reset();
form.parentNode.removeChild(form);
var target = document.getElementById('msg');
target.innerHTML = response.message + ',<a href="exec">點此</a>回首頁';
localStorage.setItem('user-token', response.token);
}

眼尖的你可以察覺,回到首頁的連結只寫了exec是為什麼呢?

這是因為這篇裡我們用javascript對BASE標籤修改,以簡化首頁及相對路徑等連結的撰寫方式,所以需要加一段程式碼在此頁面中。

google.script.run
.withSuccessHandler(function (url) {
var base = document.getElementsByTagName('base')[0]
if (!base) {
base = document.createElement('base')
document.head.appendChild(base)
}
base.target = '_top'
base.href = url
})
.getServerUrl()

對於登入的功能其實到這裡已經完成了。

不過,你用起來會覺得怪怪的,怎重新進入還是會顯示登入表單,應該跟已登入的訊息一樣才對吧! 是的,這就是一些UX

2. 改善登入後重新進入的流程

使用者登入後又進入登入頁面的流程,在原本並沒有考慮到,所以頁面並不會因為你有沒有登入而顯示不同的內容。

要解決這個問題我們首先得要能夠確認登入的狀態,所以我們要使用首頁中用來確認登入的authLogin()函數。

在body部份加入了onload事件處理,當頁面被載入的時候就執行登入狀態的檢查。並且為了讓使用者體驗更好,我們選擇預設隱藏表單(display: none),待登入檢查後再決定顯示表單的內容。

<body onload="showFormIfHavntLogin()">
<h1>登入</h1>
<form onsubmit="onSubmit(event)" id="login-form" style="display: none;">

這裡的form我們給它id,這是因為我們需要用來指定它顯示狀態。

你也許會想到,把onload移到form標籤就可以用event.target取得form了吧! 就不需要給它id了吧!

想法不錯但是現實不是如此,並非所有標籤在載入時都會有onload事件,所以我們還是設定個id,方便我們指定是這個form來做事情。

function showFormIfHavntLogin() {
var form = document.getElementById('login-form');
var token = localStorage.getItem('user-token');
try {
google.script.run.withSuccessHandler(hasLogined)
.withFailureHandler(notLogin)
.authLogin(token);
} catch (error) {
notLogin(error);
}
function hasLogined(login_user) {
form.style.display = 'none';
onCompleted({ message: '您已登入' }, form);
}
function notLogin(error) {
console.error(error);
form.style.display = 'flex';
}
}



留言