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

閱讀時間約 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 就窒礙難行的我果然想的太狹隘了。

3會員
5內容數
我是Sail,這裡主要分享一些自己覺得有趣的前端議題。
留言0
查看全部
發表第一個留言支持創作者!
廖偉帆的沙龍 的其他內容
data-* attributes 是 HTML 內建的屬性,可將網頁的狀態與元素進行綁定。而Tailwind CSS 在 3.2 版更新中推出使用 data-* attributes 自訂樣式的功能,讓樣式設定可以更動態多變。
data-* attributes 是 HTML 內建的屬性,可將網頁的狀態與元素進行綁定。而Tailwind CSS 在 3.2 版更新中推出使用 data-* attributes 自訂樣式的功能,讓樣式設定可以更動態多變。
你可能也想看
Google News 追蹤
Thumbnail
這個秋,Chill 嗨嗨!穿搭美美去賞楓,裝備款款去露營⋯⋯你的秋天怎麼過?秋日 To Do List 等你分享! 秋季全站徵文,我們準備了五個創作主題,參賽還有機會獲得「火烤兩用鍋」,一起來看看如何參加吧~
Thumbnail
美國總統大選只剩下三天, 我們觀察一整週民調與金融市場的變化(包含賭局), 到本週五下午3:00前為止, 誰是美國總統幾乎大概可以猜到60-70%的機率, 本篇文章就是以大選結局為主軸來討論近期甚至到未來四年美股可能的改變
Thumbnail
Faker昨天真的太扯了,中國主播王多多點評的話更是精妙,分享給各位 王多多的點評 「Faker是我們的處境,他是LPL永遠繞不開的一個人和話題,所以我們特別渴望在決賽跟他相遇,去直面我們的處境。 我們曾經稱他為最高的山,最長的河,以為山海就是盡頭,可是Faker用他28歲的年齡...
Thumbnail
在一個被神秘力量所統治的古代王國,有一位年輕的煉丹師名叫澤恩。澤恩夢想創造出一種神奇的藥丹,能夠提升武者的內力與健康,名為「九五之丹」。
Thumbnail
根據最高法院民事大法庭的裁定,債權人可以向法院聲請強制執行債務人的人壽保險契約,但實際執行上仍存在挑戰。本文探討法院裁定的影響及主流見解。
Thumbnail
2023年6月16日,工業和資訊化部科技司公示了《化學品分類和標籤規範 第1部分:通則》、《危險貨物運輸包裝 內裝多種危險品的包裝安全技術規範》等12項強制性國家標準的徵求意見稿及編制說明,為進一步聽取社會各界意見。(* 文末附12項強制性國家標準主要內容等一覽表)
Thumbnail
律師,我欠債數年,現已有穩定工作,但遭到債權人強制執行三分之一的薪水,讓我生活陷入困難。聽書記官說,可以證明有扶養或是每月最低生活費支出的事實,就可以減少執行的數額,請問要怎麼證明?
Thumbnail
EP45上【成長筆記】八年級生的人格特質?《我們,MZ世代》(1) ▌《我們,MZ世代》這本書,解釋八年級生的出身背景、生長環境,以及人生觀。 ▌價值觀,隨時代變化! ▌八年級生有著強大的「求生欲」! MZ世代的人格特質? ⭐️ 數位原住民和數位移民,有什麼不同? ⭐️ 為什麼八年級可以接受這種職業
Thumbnail
你有開課的夢想嗎?一直以來都很想錄製一套可以幫助知識工作做好知識理解的塗鴉筆記課程!我一直對這個主題有濃厚的興趣,希望也有更多夥伴能加入,體驗塗鴉筆記如何改變自己的生活與工作。本來開課的想法都只留在混亂的規劃文件中,但最近因為一些事件,覺得這套課程的產生將不再只是文件中的一些想像了!
Thumbnail
桃園市長鄭文燦已任滿2年,年底大選在民進黨、民眾黨、國民黨三腳督的情況下,國民黨註定被民眾黨分票,情勢已「接近敗選」相當不妙。沒想到如今又橫空迫降一位羅智強,打壞國民黨的在地整合團結,不管他最後決定如何,國民黨在桃園已「註定敗選」。 桃園確定三腳督,藍營必須更加團結 柿子挑軟的吃,羅智強人設崩壞
Thumbnail
房子被法拍的原因,主要是欠債不還、欠稅不繳,或是家人共同持有的房子要藉由拍賣來分錢等因素,使得房子被債權人 #強制執行 ,而遭法院拍賣,來抵債。 [細節可參考這篇-法拍屋怎麼來的] 什麼是強制執行? 簡單來說: 如何聲請強制執行? · 在聲請強制執行之前,必須要經過2個步驟: 第一步:取得執行名義
Thumbnail
官司打贏拿到勝訴判決書,不並是坐著就會拿到錢了,接著才是重點→要聲請請強制執行,查封、變賣債務人的財產,這些程序很複雜嗎?別擔心,本篇文章來詳細告訴你/妳!
Thumbnail
這個秋,Chill 嗨嗨!穿搭美美去賞楓,裝備款款去露營⋯⋯你的秋天怎麼過?秋日 To Do List 等你分享! 秋季全站徵文,我們準備了五個創作主題,參賽還有機會獲得「火烤兩用鍋」,一起來看看如何參加吧~
Thumbnail
美國總統大選只剩下三天, 我們觀察一整週民調與金融市場的變化(包含賭局), 到本週五下午3:00前為止, 誰是美國總統幾乎大概可以猜到60-70%的機率, 本篇文章就是以大選結局為主軸來討論近期甚至到未來四年美股可能的改變
Thumbnail
Faker昨天真的太扯了,中國主播王多多點評的話更是精妙,分享給各位 王多多的點評 「Faker是我們的處境,他是LPL永遠繞不開的一個人和話題,所以我們特別渴望在決賽跟他相遇,去直面我們的處境。 我們曾經稱他為最高的山,最長的河,以為山海就是盡頭,可是Faker用他28歲的年齡...
Thumbnail
在一個被神秘力量所統治的古代王國,有一位年輕的煉丹師名叫澤恩。澤恩夢想創造出一種神奇的藥丹,能夠提升武者的內力與健康,名為「九五之丹」。
Thumbnail
根據最高法院民事大法庭的裁定,債權人可以向法院聲請強制執行債務人的人壽保險契約,但實際執行上仍存在挑戰。本文探討法院裁定的影響及主流見解。
Thumbnail
2023年6月16日,工業和資訊化部科技司公示了《化學品分類和標籤規範 第1部分:通則》、《危險貨物運輸包裝 內裝多種危險品的包裝安全技術規範》等12項強制性國家標準的徵求意見稿及編制說明,為進一步聽取社會各界意見。(* 文末附12項強制性國家標準主要內容等一覽表)
Thumbnail
律師,我欠債數年,現已有穩定工作,但遭到債權人強制執行三分之一的薪水,讓我生活陷入困難。聽書記官說,可以證明有扶養或是每月最低生活費支出的事實,就可以減少執行的數額,請問要怎麼證明?
Thumbnail
EP45上【成長筆記】八年級生的人格特質?《我們,MZ世代》(1) ▌《我們,MZ世代》這本書,解釋八年級生的出身背景、生長環境,以及人生觀。 ▌價值觀,隨時代變化! ▌八年級生有著強大的「求生欲」! MZ世代的人格特質? ⭐️ 數位原住民和數位移民,有什麼不同? ⭐️ 為什麼八年級可以接受這種職業
Thumbnail
你有開課的夢想嗎?一直以來都很想錄製一套可以幫助知識工作做好知識理解的塗鴉筆記課程!我一直對這個主題有濃厚的興趣,希望也有更多夥伴能加入,體驗塗鴉筆記如何改變自己的生活與工作。本來開課的想法都只留在混亂的規劃文件中,但最近因為一些事件,覺得這套課程的產生將不再只是文件中的一些想像了!
Thumbnail
桃園市長鄭文燦已任滿2年,年底大選在民進黨、民眾黨、國民黨三腳督的情況下,國民黨註定被民眾黨分票,情勢已「接近敗選」相當不妙。沒想到如今又橫空迫降一位羅智強,打壞國民黨的在地整合團結,不管他最後決定如何,國民黨在桃園已「註定敗選」。 桃園確定三腳督,藍營必須更加團結 柿子挑軟的吃,羅智強人設崩壞
Thumbnail
房子被法拍的原因,主要是欠債不還、欠稅不繳,或是家人共同持有的房子要藉由拍賣來分錢等因素,使得房子被債權人 #強制執行 ,而遭法院拍賣,來抵債。 [細節可參考這篇-法拍屋怎麼來的] 什麼是強制執行? 簡單來說: 如何聲請強制執行? · 在聲請強制執行之前,必須要經過2個步驟: 第一步:取得執行名義
Thumbnail
官司打贏拿到勝訴判決書,不並是坐著就會拿到錢了,接著才是重點→要聲請請強制執行,查封、變賣債務人的財產,這些程序很複雜嗎?別擔心,本篇文章來詳細告訴你/妳!