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

