【问题标题】:Session timeout warning modal using react使用反应的会话超时警告模式
【发布时间】:2016-12-10 23:45:01
【问题描述】:

如果用户不采取任何操作,我需要在 13 分钟不活动后显示超时警告模式,并在 15 分钟后结束会话。我需要使用 reactjs 来实现这一点。我在https://www.npmjs.com/package/react-timeout#react-classic-verbose 检查了反应超时,但这并没有帮助。 如果有人知道这样做的方法,请与我分享。

【问题讨论】:

  • 在我的脑海中,为什么不在组件的state 中定义一个active 属性。通过setTimeout 设置超时以在13 分钟不活动后将active 设置为false。每次用户移动鼠标/触摸屏幕时,重置超时。在主应用程序组件中,您可以执行类似于结束会话的操作。

标签: reactjs session-timeout react-modal


【解决方案1】:

你可以像这样创建一个高阶组件,并且可以通过高阶组件传递子组件

HOC:

`//代码

export default function(ComposedClass) {
  class AutoLogout extends React.Component {
    constructor(props) {
      super(props);
      this.state = {
        warningTime: 1000 * 60 * 10,
        signoutTime: 1000 * 60 * 15,
      };
    }

    componentDidMount() {
      this.events = [
        'load',
        'mousemove',
        'mousedown',
        'click',
        'scroll',
        'keypress'
      ];

      for (var i in this.events) {
        window.addEventListener(this.events[i], this.resetTimeout);
      }

      this.setTimeout();
    }

    clearTimeoutFunc = () => {
      if (this.warnTimeout) clearTimeout(this.warnTimeout);

      if (this.logoutTimeout) clearTimeout(this.logoutTimeout);
    };

    setTimeout = () => {
      this.warnTimeout = setTimeout(this.warn, this.state.warningTime);
      this.logoutTimeout = setTimeout(this.logout, this.state.signoutTime);
    };

    resetTimeout = () => {
      this.clearTimeoutFunc();
      this.setTimeout();
    };

    warn = () => {
      window.alert("You will be logged out automatically in 1 minute")
      console.log('You will be logged out automatically in 1 minute.');
    };

    logout = () => {
      // Send a logout request to the API
      console.log('Sending a logout request to the API...');
      this.destroy();
    };

    destroy = () => {
     //clear the session
      browserHistory.push('/');
      window.location.assign('/');
    };

    render() {

      return (
        <div>
          <ComposedClass {...this.props} />
        </div>
      );
    }
  }
}

`

您可以将此 HOC 包装到路由文件中由于不活动而要向用户发出警告的所有组件

&lt;Route path="/test" component={HOC(comonent)} /&gt;

上面的代码组件将是您要添加此功能的页面。

【讨论】:

  • 你有一个工作示例来演示这样的东西吗?
  • 警报框不会停止事件循环,防止注销吗?
  • stackoverflow.com/users/3368818/j-woodchuck - 你得到这份工作了吗?如果是这样,您可以发布您的解决方案吗?
  • 我得到这个:元素类型无效:需要一个字符串(对于内置组件)或一个类/函数(对于复合组件),但得到:未定义。您可能忘记从定义组件的文件中导出组件,或者您可能混淆了默认导入和命名导入。
  • 如何从注销中调用调度操作?
【解决方案2】:

如果你想用 Package 实现同样的效果,那么你可以使用 React Idle Timer Package 编写下面的代码

npm i react-idle-timer

import React from 'react'
import { useIdleTimer } from 'react-idle-timer'
import { useHistory } from 'react-router'

const SESSION_IDEL_MINUTES = 4;

const AutoLagoutTimer = (props: any) => {
    const { ComposedClass } = props
    const history = useHistory()

    const handleOnIdle = (event: any) => {
        // SHOW YOUR MODAL HERE AND LAGOUT
        console.log('user is idle', event)
        console.log('last active', getLastActiveTime())
        history.push("/lagout")
    }

    const {getLastActiveTime } = useIdleTimer({
        timeout: 1000 * 60 * SESSION_IDEL_MINUTES,
        onIdle: handleOnIdle,
        debounce: 500,
    })

    return <ComposedClass />
}

export default AutoLagoutTimer;

对于所有受保护的路由,您可以使用如下所示的组件进行包装

     <Route path={"/dashboard"}>
        <AutoLagoutTimer ComposedClass={Dashboard} />
    </Route>

【讨论】:

    【解决方案3】:

    这是模态空闲警告的完整示例。

    假设您在此处使用 reactstrap 进行样式设置。

    import React, {useState, useEffect} from 'react';
    import {Modal, ModalHeader, ModalBody, ModalFooter} from 'reactstrap';
    
    
    function IdleMonitor()
    {
      //Modal
      const [idleModal, setIdleModal] = useState(false);
    
      let idleTimeout = 1000 * 60 * 1;  //1 minute
      let idleLogout = 1000 * 60 * 2; //2 Minutes
      let idleEvent; 
      let idleLogoutEvent;
    
      /**
       * Add any other events listeners here
       */
      const events = [
        'mousemove',
        'click',
        'keypress'
      ];
    
    
      /**
       * @method sessionTimeout
       * This function is called with each event listener to set a timeout or clear a timeout.
       */
      const sessionTimeout = () => 
      {  
        if(!!idleEvent) clearTimeout(idleEvent);
        if(!!idleLogoutEvent) clearTimeout(idleLogoutEvent);
    
        idleEvent = setTimeout(() => setIdleModal(true), idleTimeout); //show session warning modal.
        idleLogoutEvent = setTimeout(() => logOut, idleLogout); //Call logged out on session expire.
      };
    
      /**
       * @method extendSession
       * This function will extend current user session.
       */
      const extendSession = () => 
      {
        console.log('user wants to stay logged in');
      }
    
    
      /**
       * @method logOut
       * This function will destroy current user session.
       */
      const logOut = () => 
      {
        console.log('logging out');
      }
    
      useEffect(() => 
      {
        for (let e in events) 
        {
          window.addEventListener(events[e], sessionTimeout);
        }
    
        return () => 
        {
          for(let e in events)
          {
            window.removeEventListener(events[e], sessionTimeout);
          }
        }
      },[]);
    
    
        return (
    
          <Modal isOpen={idleModal} toggle={() => setIdleModal(false)}>
            <ModalHeader toggle={() => setIdleModal(false)}>
                Session expire warning
            </ModalHeader>
            <ModalBody>
                your session will expire in {idleLogout / 60 / 1000} minutes. Do you want to extend the session?
            </ModalBody>
            <ModalFooter>
              <button className="btn btn-info"  onClick={()=> logOut()}>Logout</button>
              <button className="btn btn-success" onClick={()=> extendSession()}>Extend session</button>
            
            </ModalFooter>
          </Modal>
        )
    
      }
    
    export default IdleMonitor;

    创建该类后,您可以像这样从任何地方简单地调用它

    <IdleMonitor/>
    

    别忘了导入它。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-05-18
      • 2016-02-06
      • 2016-09-11
      • 2014-07-18
      • 1970-01-01
      • 2012-07-17
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多