React纯前端模拟实现登录鉴权

 更新时间:2024年04月16日 09:48:18   作者:慕仲卿  
这篇文章主要为大家详细介绍了React纯前端模拟实现登录鉴权的相关知识,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下

一、目标

本文档旨在阐述前端模拟登录鉴权的实现机制,该机制通过前端技术和 LocalStorage 实现用户的登录状态管理,以确保用户未登录时无法直接访问系统的内层页面,并通过定时器更新登录状态,以保持用户的活动会话。

二、鉴权规则设计

2.1 登录状态判断

系统通过检查 LocalStorage 中的 isLogin 字段来判断用户是否已登录。若 LocalStorage 中不存在 isLogin 字段,则视为用户未登录。

2.2 未登录重定向

若用户未登录,且尝试直接访问以下受保护的页面:'/FactoryView', '/FactoryView/ServerNumView', '/FactoryView/ServerNumView/DeviceView', '/GlobalView', '/AdminAreaView',系统将会自动将用户重定向至 '/Login' 页面。

2.3 登录状态设置

用户成功登录后,系统会在 LocalStorage 中设置 isLogin 字段,其值为当前的时间戳(以毫秒为单位)。

2.4 定时更新登录状态

用户一旦进入受保护的内层页面,页面会启动一个定时器,该定时器每 5 秒钟更新 LocalStorage 中的 isLogin 字段,将其值设置为当前时间戳。这确保了只要用户保持在内层页面,其登录状态就会持续更新。

2.5 会话超时处理

若用户关闭了 App 页面或离开了受保护的内层页面,定时器将停止工作,isLogin 字段的值将不再更新。当用户再次尝试访问受保护页面时,系统会检查 isLogin 中的时间戳与当前时间的差异。若差异超过 30 分钟,则视为会话超时,用户将被重定向至登录页面。反之,若时间差在 30 分钟以内,则允许用户访问内层页面,并重启定时器更新 isLogin 字段。

2.6 流程图

上述规则可以使用下面的流程图表示为:

三、Hook代码实现

为实现上述鉴权逻辑,我们创建了一个自定义 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使用方式

在需要实现登录鉴权的内层页面中,引入并使用该 Hook:

import { useIntervalWhenStarted } from "@/hooks";

// ... 页面组件代码 ...

useIntervalWhenStarted();

// ... 页面组件其余代码 ...

四、在最外层对路由进行拦截

下面就以 UMI.js 框架为例,说明如何拦截路由。

根据 UMI.js 的结构特性,所有组件的渲染必定经过预设的 layout,因此在 layouts/index.tsx 的组件渲染之前对路由进行检测,根据其是否否和要求进行拦截:

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 就是用来检测用户是否具有查看内层页面权限的,其实现为:

/**
 * 检查登录状态,如果没有登录则强制到登录页
 */
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',
      })
    }
  }
}

五、亮点说明

亮点一:无服务器端的会话管理

传统的会话管理通常需要服务器端的支持,通过服务器来记录用户的登录状态和会话信息。然而,在本鉴权机制中,我们采用了前端技术和 LocalStorage 来实现会话管理,无需依赖服务器端。这降低了服务器的负载,并提高了应用的响应速度。

亮点二:自动会话续期

通过在内层页面设置定时器,每 5 秒钟自动更新 LocalStorage 中的 isLogin 字段,实现了会话的自动续期。这种方法能够确保用户在保持页面活跃的情况下,其会话始终有效,避免了用户频繁登录的烦恼。

亮点三:灵活的会话超时处理

本机制通过比较 isLogin 字段中的时间戳与当前时间的差异,来判断会话是否超时。这种方法既灵活又高效,允许系统在用户离开页面后的一段时间内保持会话有效,同时又能及时识别和处理超时情况,提升了用户体验和系统安全性。

亮点四:模块化、可复用的Hook实现

通过创建一个自定义的 Hook(useIntervalWhenStarted),我们将鉴权逻辑封装成了一个独立的、可复用的模块。这使得该逻辑可以轻松地集成到任何需要鉴权的 React 组件中,提高了代码的复用性和可维护性。

六、总结

通过上述设计,我们实现了一个前端模拟的登录鉴权机制。该机制通过 LocalStorage 和定时器来管理用户的登录状态,确保了未登录用户无法直接访问受保护的内层页面,并通过定时器持续更新登录状态以防止会话超时。

到此这篇关于React纯前端模拟实现登录鉴权的文章就介绍到这了,更多相关React登录鉴权内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • React中的页面跳转方式示例详解

    React中的页面跳转方式示例详解

    React Router提供了几种不同的跳转方式,包括使用组件进行页面跳转、使用组件进行重定向,以及使用编程式导航进行跳转,这篇文章主要介绍了React中的页面跳转方式详解,需要的朋友可以参考下
    2023-09-09
  • React Electron生成桌面应用过程

    React Electron生成桌面应用过程

    这篇文章主要介绍了React+Electron快速创建并打包成桌面应用,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习吧
    2022-12-12
  • React-Native之定时器Timer的实现代码

    React-Native之定时器Timer的实现代码

    本篇文章主要介绍了React-Native之定时器Timer的实现代码,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-10-10
  • react系列从零开始_简单谈谈react

    react系列从零开始_简单谈谈react

    下面小编就为大家带来一篇react系列从零开始_简单谈谈react。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-07-07
  • React diff算法原理详细分析

    React diff算法原理详细分析

    经典的diff算法中,将一棵树转为另一棵树的最低时间复杂度为 O(n^3),其中n为树种节点的个数。假如采用这种diff算法,一个应用有1000个节点的情况下,需要比较十亿次才能将dom树更新完成,显然这个性能是无法让人接受的
    2022-11-11
  • 浅谈React Event实现原理

    浅谈React Event实现原理

    这篇文章主要介绍了浅谈React Event实现原理,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-09-09
  • React之如何在Suspense中优雅地请求数据

    React之如何在Suspense中优雅地请求数据

    Suspense 是 React 中的一个组件,直译过来有悬挂的意思,能够将其包裹的异步组件挂起,直到组件加载完成后再渲染,本文详细介绍了如何在Suspense中请求数据,感兴趣的小伙伴可以参考阅读本文
    2023-04-04
  • React找不到模块“./index.module.scss”或其相应的类型声明及解决方法

    React找不到模块“./index.module.scss”或其相应的类型声明及解决方法

    这篇文章主要介绍了React找不到模块“./index.module.scss”或其相应的类型声明及解决方法,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2023-09-09
  • React中引用CSS方式及写法大全(三种方式)

    React中引用CSS方式及写法大全(三种方式)

    在React中引用CSS的方法有多种,可以根据个人的喜好和项目的需求来选择,本文主要介绍了React中引用CSS方式及写法大全,感兴趣的可以了解一下
    2023-10-10
  • react进阶教程之异常处理机制error Boundaries

    react进阶教程之异常处理机制error Boundaries

    在react中一旦出错,如果每个组件去处理出错情况则比较麻烦,下面这篇文章主要给大家介绍了关于react进阶教程之异常处理机制error Boundaries的相关资料,文中通过实例代码介绍的非常详细,需要的朋友可以参考下
    2022-08-08

最新评论