React純前端模擬實現(xiàn)登錄鑒權(quán)
一、目標(biāo)
本文檔旨在闡述前端模擬登錄鑒權(quán)的實現(xiàn)機制,該機制通過前端技術(shù)和 LocalStorage
實現(xiàn)用戶的登錄狀態(tài)管理,以確保用戶未登錄時無法直接訪問系統(tǒng)的內(nèi)層頁面,并通過定時器更新登錄狀態(tài),以保持用戶的活動會話。
二、鑒權(quán)規(guī)則設(shè)計
2.1 登錄狀態(tài)判斷
系統(tǒng)通過檢查 LocalStorage
中的 isLogin
字段來判斷用戶是否已登錄。若 LocalStorage
中不存在 isLogin
字段,則視為用戶未登錄。
2.2 未登錄重定向
若用戶未登錄,且嘗試直接訪問以下受保護的頁面:'/FactoryView', '/FactoryView/ServerNumView', '/FactoryView/ServerNumView/DeviceView', '/GlobalView', '/AdminAreaView'
,系統(tǒng)將會自動將用戶重定向至 '/Login'
頁面。
2.3 登錄狀態(tài)設(shè)置
用戶成功登錄后,系統(tǒng)會在 LocalStorage
中設(shè)置 isLogin
字段,其值為當(dāng)前的時間戳(以毫秒為單位)。
2.4 定時更新登錄狀態(tài)
用戶一旦進入受保護的內(nèi)層頁面,頁面會啟動一個定時器,該定時器每 5 秒鐘更新 LocalStorage
中的 isLogin
字段,將其值設(shè)置為當(dāng)前時間戳。這確保了只要用戶保持在內(nèi)層頁面,其登錄狀態(tài)就會持續(xù)更新。
2.5 會話超時處理
若用戶關(guān)閉了 App
頁面或離開了受保護的內(nèi)層頁面,定時器將停止工作,isLogin
字段的值將不再更新。當(dāng)用戶再次嘗試訪問受保護頁面時,系統(tǒng)會檢查 isLogin
中的時間戳與當(dāng)前時間的差異。若差異超過 30 分鐘,則視為會話超時,用戶將被重定向至登錄頁面。反之,若時間差在 30 分鐘以內(nèi),則允許用戶訪問內(nèi)層頁面,并重啟定時器更新 isLogin
字段。
2.6 流程圖
上述規(guī)則可以使用下面的流程圖表示為:
三、Hook代碼實現(xiàn)
為實現(xiàn)上述鑒權(quán)邏輯,我們創(chuàng)建了一個自定義 Hook :useIntervalWhenStarted
。這個 Hook 用于在組件掛載時啟動一個定時器,該定時器每5秒更新 LocalStorage
中的 isLogin
字段。
3.1 Hook代碼
import { useState, useEffect } from 'react'; const useIntervalWhenStarted = () => { useEffect(() => { let timer = null; timer = setInterval(() => { window.localStorage.setItem('isLogin', (+new Date()).toString()); }, 5 * 1000); return () => { if (timer) { clearInterval(timer); } }; }, []); return []; }; export { useIntervalWhenStarted };
3.2 Hook使用方式
在需要實現(xiàn)登錄鑒權(quán)的內(nèi)層頁面中,引入并使用該 Hook:
import { useIntervalWhenStarted } from "@/hooks"; // ... 頁面組件代碼 ... useIntervalWhenStarted(); // ... 頁面組件其余代碼 ...
四、在最外層對路由進行攔截
下面就以 UMI.js 框架為例,說明如何攔截路由。
根據(jù) UMI.js 的結(jié)構(gòu)特性,所有組件的渲染必定經(jīng)過預(yù)設(shè)的 layout
,因此在 layouts/index.tsx
的組件渲染之前對路由進行檢測,根據(jù)其是否否和要求進行攔截:
import React from 'react'; import store from 'store'; import { ConfigProvider } from 'antd'; import { Outlet } from '@umijs/max'; import { checkIfLogin } from "@/utils/utils"; import Intl from 'react-intl-universal'; import intlzhCN from '@/locales/zh-CN'; import intlenUS from '@/locales/en-US'; import "./index.less"; const locale = { 'zh-CN': require('antd/lib/locale/zh_CN'), 'en-US': require('antd/lib/locale/en_US'), }; const BasicLayout: React.FC<any> = (props) => { const { children } = props; console.log(props); const lang = store.get('umi_locale') || 'zh-CN'; Intl.init({ currentLocale: lang, locales: { 'zh-CN': intlzhCN, 'en-US': intlenUS, }, }); checkIfLogin(); return ( <ConfigProvider componentSize="small" locale={locale[lang].default}> {children} <Outlet /> </ConfigProvider> ); }; export default BasicLayout;
上面的代碼中 checkIfLogin
就是用來檢測用戶是否具有查看內(nèi)層頁面權(quán)限的,其實現(xiàn)為:
/** * 檢查登錄狀態(tài),如果沒有登錄則強制到登錄頁 */ export const checkIfLogin = () => { const gap = 30 * 60 * 1000; const login = window.localStorage.getItem('isLogin'); const location = useLocation(); const { pathname } = location; if(['/Login','/login'].includes(pathname)) return; if(!login) { history.push({ pathname: '/Login', }) } else { const timeStamp = parseInt(login); const current = +new Date(); if (current-timeStamp>gap) { window.localStorage.removeItem('isLogin'); history.push({ pathname: '/Login', }) } } }
五、亮點說明
亮點一:無服務(wù)器端的會話管理
傳統(tǒng)的會話管理通常需要服務(wù)器端的支持,通過服務(wù)器來記錄用戶的登錄狀態(tài)和會話信息。然而,在本鑒權(quán)機制中,我們采用了前端技術(shù)和 LocalStorage
來實現(xiàn)會話管理,無需依賴服務(wù)器端。這降低了服務(wù)器的負載,并提高了應(yīng)用的響應(yīng)速度。
亮點二:自動會話續(xù)期
通過在內(nèi)層頁面設(shè)置定時器,每 5 秒鐘自動更新 LocalStorage
中的 isLogin
字段,實現(xiàn)了會話的自動續(xù)期。這種方法能夠確保用戶在保持頁面活躍的情況下,其會話始終有效,避免了用戶頻繁登錄的煩惱。
亮點三:靈活的會話超時處理
本機制通過比較 isLogin
字段中的時間戳與當(dāng)前時間的差異,來判斷會話是否超時。這種方法既靈活又高效,允許系統(tǒng)在用戶離開頁面后的一段時間內(nèi)保持會話有效,同時又能及時識別和處理超時情況,提升了用戶體驗和系統(tǒng)安全性。
亮點四:模塊化、可復(fù)用的Hook實現(xiàn)
通過創(chuàng)建一個自定義的 Hook(useIntervalWhenStarted
),我們將鑒權(quán)邏輯封裝成了一個獨立的、可復(fù)用的模塊。這使得該邏輯可以輕松地集成到任何需要鑒權(quán)的 React 組件中,提高了代碼的復(fù)用性和可維護性。
六、總結(jié)
通過上述設(shè)計,我們實現(xiàn)了一個前端模擬的登錄鑒權(quán)機制。該機制通過 LocalStorage
和定時器來管理用戶的登錄狀態(tài),確保了未登錄用戶無法直接訪問受保護的內(nèi)層頁面,并通過定時器持續(xù)更新登錄狀態(tài)以防止會話超時。
到此這篇關(guān)于React純前端模擬實現(xiàn)登錄鑒權(quán)的文章就介紹到這了,更多相關(guān)React登錄鑒權(quán)內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
React?useEffect異步操作常見問題小結(jié)
本文主要介紹了React?useEffect異步操作常見問題小結(jié),文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2022-06-06React中使用echarts-for-react的方法示例
echarts-for-react則是ECharts在React生態(tài)中的官方封裝組件,它讓開發(fā)者能夠輕松地在React應(yīng)用中集成ECharts圖表,本文就來介紹一下echarts-for-react的使用,感興趣的可以了解一下2025-03-03