如何強制登出閒置網頁的使用者

更新於 發佈於 閱讀時間約 5 分鐘

大綱

  • 為什麼要登出使用者?
  • 思路
  • 實作過程
  • 心得



為什麼要登出使用者?

  • 防止未經授權的人,在使用者暫離時使用系統,公用或共享電腦的環境中尤其重要。
  • 只要使用者處於登入狀態,就會暴露在個人資料被他人操縱或利用的風險中,因此登出閒置使用者對資安也很重要。


思路

要如何從前端登出使用者?

若已連接後端API,使用者會在第一次登入時,拿到 cookie。前端可透過 document.cookie 讀取、寫入甚至刪除 cookie。(cookie 並未加密,仍有安全疑慮) 但因為專案尚未連接登入 API,似乎只能把使用者的登入狀態放在 localStorage 操作。


該如何設置、清除和重置 timer?

在 JavaScript 中,透過瀏覽器或Node 等 runtime,可以用 setTimeoutsetInterval 方法來設置計時器。

setTimeout 會設置一次性的計時器,並回傳一個數字id,可利用clearTimeout(id)將該計時器清除。 setInterval 則會設置一個持續計時的計時器,除非利用回傳的 id 執行clearInterval(id) ,否則不會停止計時。登出閒置使用者的功能,看似是要持續監聽使用者行為,實際上會需要在使用者閒置和重新點擊視窗時重置計時器,因此我選用 setTimeout


實作過程

專案的頁面會有很多,可以想見需要一個可重複運用在各元件的邏輯,來檢查使用者的閒置時間是否超過上限,因此我選用 Vue 3 Composition API 的 composable 在元件之間共享邏輯。

在登入表單中,會把使用者 id 透過 activeUserId 這個 key 存進 localStorage 中,等下登出時就會做刪除。

function submitForm() {
console.log("Submitting:", email.value, password.value);
isLoggedIn.value = true;
const userId = (currentUserId.value = Math.random());
localStorage.setItem("activeUserId", userId);
}

使用者被登出後,需要將其導向首頁,這個行為由 Vue Router 的 router.replace() 負責。之所以用 replace 而非 push,是要在瀏覽器的 history 物件中,用首頁取代登出前所在的頁面,防止使用者利用瀏覽器的上一頁按鈕回到之前的頁面。

isLoggedOut.value = true;
console.log("User is logged out due to inactivity");
router.replace("/");

Composable

建立一個 useLogoutIdle composable,每次呼叫時,會先根據 localStorage 裡面有無 activeUserId 值判斷使用者是否登出,接著做 timeout 的處理:在每次window 發生 blur (失去焦點) 事件時,就設置新的計時器,而若使用者點擊視窗觸發 onMouseDown 事件,則將計時器清除。

在 hook 裡面宣告 isLoggedOut ref。

在 hook 裡面宣告 isLoggedOut ref。


完整的 hook 程式碼如下:

Toast

為了避免使用者被登出後,畫面突然跳轉而無通知,我需要一個能跳出 toast 通知的套件。在找套件時,發現之前滿受歡迎的 vue-toastificaiton 停止維護了,因此我使用 vue-toast-notification 套件來告知使用者即將被登出。



vue-toast-notification 樣式簡單好看

vue-toast-notification 樣式簡單好看


心得

此次實作還滿能體會 React 和 Vue 原生的 API 設計哲學之差異:在一般的 js 或 ts 檔案中, ref 可以在檔案中的任何位置呼叫,不像 React 的 custom hook 會限定 hook 一定要在元件頂層或是 use-* 裡面使用,這點在開發上帶來較大的彈性。但這也會容易產生盲點,例如沒有在 startTimeout 裡面帶入 timeout 參數,就會沒辦法在呼叫時吃到頂層宣告的 timeout 值,雖然這是 JS 作用域的問題,但把 hook 限制在元件裡或許比較能避免此錯誤?

直接在檔案頂層使用 ref 很方便。

直接在檔案頂層使用 ref 很方便。

localStorage 裡的資料,都可以在瀏覽器透過 JavaScript 操作,只靠它去儲存使用者的登入狀態會有問題,較安全的做法,是將使用者重新導向後,再透過後端 API 驗證才較安全。

此外,其實這個 function 並沒有符合 composable 可以在各元件抽取出變數的精神,僅止於在 元件之間共享操作 ref 的邏輯罷了,也許有比 composable 更好的做法。

最後,特別感謝 學.誌|Chris Kang 提供用計時器和 localStorage 實作的想法。原本接到需求時,覺得沒有登入 API 就窒礙難行的我果然想的太狹隘了。

avatar-img
3會員
5內容數
我是Sail,這裡主要分享一些自己覺得有趣的前端議題。
留言0
查看全部
avatar-img
發表第一個留言支持創作者!
廖偉帆的沙龍 的其他內容
data-* attributes 是 HTML 內建的屬性,可將網頁的狀態與元素進行綁定。而Tailwind CSS 在 3.2 版更新中推出使用 data-* attributes 自訂樣式的功能,讓樣式設定可以更動態多變。
data-* attributes 是 HTML 內建的屬性,可將網頁的狀態與元素進行綁定。而Tailwind CSS 在 3.2 版更新中推出使用 data-* attributes 自訂樣式的功能,讓樣式設定可以更動態多變。
你可能也想看
Google News 追蹤
Thumbnail
隨著理財資訊的普及,越來越多台灣人不再將資產侷限於台股,而是將視野拓展到國際市場。特別是美國市場,其豐富的理財選擇,讓不少人開始思考將資金配置於海外市場的可能性。 然而,要參與美國市場並不只是盲目跟隨標的這麼簡單,而是需要策略和方式,尤其對新手而言,除了選股以外還會遇到語言、開戶流程、Ap
Thumbnail
嘿,大家新年快樂~ 新年大家都在做什麼呢? 跨年夜的我趕工製作某個外包設計案,在工作告一段落時趕上倒數。 然後和兩個小孩過了一個忙亂的元旦。在深夜時刻,看到朋友傳來的解籤網站,興致勃勃熬夜體驗了一下,覺得非常好玩,或許有人玩過了,但還是想寫上來分享紀錄一下~
Thumbnail
#幫我找找我的手機 假日、放假盡量 #減少滑手機的時間,
Thumbnail
🔐 發現招募其實是一個解鎖的過程,過往的成功經驗,即便相同職缺,也會因用人單位不同,無法完全複製貼上。
Thumbnail
平常我們在 html 上常看到的例如 v-for、v-model 等等... 也是VUE已經幫我們定義好的指令,而這次我們可以依這自己的需求來建立。 此功能屬於較進階的功能,因此實戰中會比較少見,市面上還是有不少完善的套件能達到同樣效果,建議可以先往這方面察找
Thumbnail
留住新人怎麼做? 分享格子文章給朋友,人進來看一下就滑出去了...除了創作者,受眾不管上班在家,都滑手機,哪有在用電腦的?所以使用者介面要用手機UI去思考,而不是網頁UI。一個平台好不好用,能不能把使用者留住更多的時間,優化UI是重中之重。格子兼有公域和私域生態,可把變現模式可以更有趣,更多元。
Thumbnail
2023 Vue直播班筆記 - 動態路由Props,接續之前的一般動態路由。分為 "寫死" 及 "彈性" 兩種。
Thumbnail
每個座位在自己的時空裡陷落時
Thumbnail
整合測試的時候突然遇到一個突然無法登入產品網站的問題,把程式模組單獨拉出來測試又正常,觀察測試報告後發現出現發生登入異常的時間點並不固定,而且只要發生就會連續發生一段時間,程式被中斷掉。後來確認問題在...
Thumbnail
隨著理財資訊的普及,越來越多台灣人不再將資產侷限於台股,而是將視野拓展到國際市場。特別是美國市場,其豐富的理財選擇,讓不少人開始思考將資金配置於海外市場的可能性。 然而,要參與美國市場並不只是盲目跟隨標的這麼簡單,而是需要策略和方式,尤其對新手而言,除了選股以外還會遇到語言、開戶流程、Ap
Thumbnail
嘿,大家新年快樂~ 新年大家都在做什麼呢? 跨年夜的我趕工製作某個外包設計案,在工作告一段落時趕上倒數。 然後和兩個小孩過了一個忙亂的元旦。在深夜時刻,看到朋友傳來的解籤網站,興致勃勃熬夜體驗了一下,覺得非常好玩,或許有人玩過了,但還是想寫上來分享紀錄一下~
Thumbnail
#幫我找找我的手機 假日、放假盡量 #減少滑手機的時間,
Thumbnail
🔐 發現招募其實是一個解鎖的過程,過往的成功經驗,即便相同職缺,也會因用人單位不同,無法完全複製貼上。
Thumbnail
平常我們在 html 上常看到的例如 v-for、v-model 等等... 也是VUE已經幫我們定義好的指令,而這次我們可以依這自己的需求來建立。 此功能屬於較進階的功能,因此實戰中會比較少見,市面上還是有不少完善的套件能達到同樣效果,建議可以先往這方面察找
Thumbnail
留住新人怎麼做? 分享格子文章給朋友,人進來看一下就滑出去了...除了創作者,受眾不管上班在家,都滑手機,哪有在用電腦的?所以使用者介面要用手機UI去思考,而不是網頁UI。一個平台好不好用,能不能把使用者留住更多的時間,優化UI是重中之重。格子兼有公域和私域生態,可把變現模式可以更有趣,更多元。
Thumbnail
2023 Vue直播班筆記 - 動態路由Props,接續之前的一般動態路由。分為 "寫死" 及 "彈性" 兩種。
Thumbnail
每個座位在自己的時空裡陷落時
Thumbnail
整合測試的時候突然遇到一個突然無法登入產品網站的問題,把程式模組單獨拉出來測試又正常,觀察測試報告後發現出現發生登入異常的時間點並不固定,而且只要發生就會連續發生一段時間,程式被中斷掉。後來確認問題在...