前端檢測用戶登錄狀態(tài)是否過期的幾種方法
在前端開發(fā)中 , 判斷用戶登錄狀態(tài)是否過期是一個常見的需求。尤其是在復(fù)雜的場景中 , 準確判斷用戶登錄狀態(tài)是否過期是保障用戶體驗的關(guān)鍵環(huán)節(jié)。這一過程涉及到服務(wù)器與前端之間的緊密協(xié)作 , 以及多種技術(shù)手段的綜合運用 , 還是蠻有挑戰(zhàn)性的。
判斷登錄過期的主要方法有: 檢查令牌有效期 , 定時輪詢服務(wù)器 , 全局請求攔截器 , 利用web存儲中的時間戳。
一、檢查令牌有效期
對于包含有效期信息的令牌(如 JWT 中的exp字段),前端可以在每次發(fā)送請求之前對令牌進行檢查。以下是一個簡單的檢查 JWT 令牌有效期的函數(shù)示例(使用jwt-decode庫來解析 JWT):
import jwt_decode from 'jwt-decode'; function checkTokenValidity(token) { try { const decodedToken = jwt_decode(token); const currentTime = Date.now() / 1000; // 獲取當前時間(以秒為單位) if (decodedToken.exp < currentTime) { console.log('令牌已過期(令牌有效期檢查)'); return false; } return true; } catch (error) { console.log('令牌解析出錯:', error); return false; } } // 在發(fā)送請求前調(diào)用此函數(shù)檢查令牌 const token = localStorage.getItem('token'); if (checkTokenValidity(token)) { // 令牌有效,繼續(xù)發(fā)送請求 // 這里假設(shè)使用`axios`發(fā)送請求 axios.get('/api/data'); } else { console.log('登錄狀態(tài)可能已過期,需處理'); // 處理登錄過期情況,如提示用戶重新登錄 }
二、定時輪詢服務(wù)器
輪詢服務(wù)器狀態(tài)是一種主動檢查令牌是否有效的方法。前端可以定期發(fā)送請求到服務(wù)器,檢查令牌是否仍然有效。
1. 定時輪詢
設(shè)置一個定時器,每隔一定時間發(fā)送請求到服務(wù)器,檢查令牌狀態(tài):
function checkTokenStatus() { axios.get('/auth/check') .then(response => { if (!response.data.valid) { // 令牌無效,執(zhí)行登出邏輯 logout(); } }) .catch(error => { // 網(wǎng)絡(luò)錯誤或其他問題,執(zhí)行登出邏輯 logout(); }); } setInterval(checkTokenStatus, 15 * 60 * 1000); // 每15分鐘檢查一次
2.優(yōu)化輪詢頻率
需求背景: 在企業(yè)級應(yīng)用中,可能會有大量用戶同時在線,頻繁的過期檢測操作(如定時輪詢)會對系統(tǒng)性能造成過大的負擔。因此,需要采用高效的過期檢測機制,例如優(yōu)化輪詢的頻率,或者采用更智能的令牌有效期檢查算法,減少不必要的檢測次數(shù)。
為了減少對服務(wù)器的壓力,可以根據(jù)用戶的操作頻率調(diào)整輪詢頻率。例如,在用戶活躍時頻繁檢查,在用戶長時間沒有操作時減少檢查頻率。
let lastActivityTime = Date.now(); document.addEventListener('mousemove', () => lastActivityTime = Date.now()); document.addEventListener('keydown', () => lastActivityTime = Date.now()); setInterval(() => { if (Date.now() - lastActivityTime < 5 * 60 * 1000) { // 用戶5分鐘內(nèi)有操作 checkTokenStatus(); } }, 15 * 60 * 1000);
這種方法可以在確保安全性的同時減少對服務(wù)器的壓力。
三、全局請求攔截器
前端在發(fā)送請求時,可以通過檢查服務(wù)器的響應(yīng)狀態(tài)碼來判斷登錄是否過期。通常,服務(wù)器會返回401未授權(quán)狀態(tài)碼表示令牌無效或過期。
1. 捕獲401狀態(tài)碼
axios.interceptors.response.use(response => { return response; }, error => { if (error.response.status === 401) { // 令牌無效或過期,執(zhí)行登出邏輯 logout(); } return Promise.reject(error); });
2.彈出登錄提示
當捕獲到401狀態(tài)碼時 , 可以彈出登錄提示 , 引導用戶重新登錄:
function logout() { // 清除本地存儲的令牌 removeToken(); // 彈出登錄提示 alert('登錄已過期,請重新登錄'); // 跳轉(zhuǎn)到登錄頁面 window.location.href = '/login'; }
這種方法可以確保前端在令牌過期時及時響應(yīng),提高了系統(tǒng)的安全性。
四、利用web中的持久化存儲
前端可以在登錄成功時將令牌的有效期時間戳保存到Web存儲(如localStorage或sessionStorage),并在每次請求前檢查時間戳是否過期。
1.保存時間戳
在用戶登錄成功后 , 將令牌和有效期時間戳保存到 localStorage
中:
function saveToken(token, expiresIn) { const expirationTime = Date.now() + expiresIn * 1000; localStorage.setItem('token', token); localStorage.setItem('tokenExpiration', expirationTime); }
2.檢查時間戳
在每次請求前,檢查當前時間是否超過保存的時間戳:
function isTokenExpired() { const expirationTime = localStorage.getItem('tokenExpiration'); return Date.now() >= expirationTime; }
如果時間戳過期,則提示用戶重新登錄:
axios.interceptors.request.use(config => { if (isTokenExpired()) { // 令牌過期,執(zhí)行登出邏輯 logout(); } else { const token = localStorage.getItem('token'); config.headers['Authorization'] = `Bearer ${token}`; } return config; }, error => { return Promise.reject(error); });
特定場景中的優(yōu)化方案
前面都是檢測用戶登錄狀態(tài)的方法 , 這個時候 產(chǎn)品經(jīng)理
提出一個需要優(yōu)化的點:
需求背景: 在業(yè)務(wù)流程中,用戶可能正在進行重要的操作(如填寫復(fù)雜的表單、進行數(shù)據(jù)分析等)。當?shù)卿洜顟B(tài)過期時,應(yīng)盡量避免突然中斷用戶操作,如在不影響用戶當前輸入的情況下彈出提示框,引導用戶重新登錄。
那我們?nèi)绾螌崿F(xiàn)這個需求呢? 答案是--------優(yōu)雅降級
當檢測到登錄狀態(tài)過期時,為了避免給用戶帶來突兀的體驗,我們需要采用優(yōu)雅降級的方式。例如,可以通過模態(tài)框提示用戶登錄過期信息,并允許用戶重新登錄,同時要保留當前頁面的狀態(tài)。以下是一個使用 React.js 實現(xiàn)的簡單示例(使用react-bootstrap
的模態(tài)框組件):
首先,確保項目中已經(jīng)安裝了react-bootstrap
和react-router-dom
庫。
import React, { useState } from 'react'; import { Button, Modal } from 'react-bootstrap'; import { useHistory } from 'react-router-dom'; const LoginExpiredModal = () => { const [dialogVisible, setDialogVisible] = useState(false); const history = useHistory(); // 這里模擬存儲當前頁面的一些狀態(tài)信息,比如表單數(shù)據(jù)等 const currentPageState = { formData: { name: 'John', age: 30 } }; const showModal = () => { setDialogVisible(true); }; const handleClose = () => { // 將當前頁面狀態(tài)存儲到localStorage中 localStorage.setItem('pageState', JSON.stringify(currentPageState)); // 重定向到登錄頁面 history.push('/login'); }; return ( <div> <Button onClick={showModal}>模擬觸發(fā)登錄過期提示</Button> <Modal show={dialogVisible} onHide={handleClose}> <Modal.Header closeButton> <Modal.Title>登錄過期</Modal.Title> </Modal.Header> <Modal.Body> <p>您的登錄已過期,請重新登錄。</p> </Modal.Body> </Modal> </div> ); }; export default LoginExpiredModal;
總結(jié)
到此這篇關(guān)于前端檢測用戶登錄狀態(tài)是否過期的文章就介紹到這了,更多相關(guān)前端檢測用戶登錄狀態(tài)過期內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
JavaScript實現(xiàn)數(shù)值自動增加動畫
這篇文章主要為大家詳細介紹了JavaScript實現(xiàn)數(shù)值自動增加動畫,具有一定的參考價值,感興趣的小伙伴們可以參考一下2017-12-12jstl中判斷l(xiāng)ist中是否包含某個值的簡單方法
下面小編就為大家?guī)硪黄猨stl中判斷l(xiāng)ist中是否包含某個值的簡單方法。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2016-10-10flash javascript之間的通訊方法小結(jié)
不用getURL和fsCommand方法個國外的通信方法,值得一看2008-12-12