You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React登录页添加会话超时功能求助:超时前提醒+自动跳转

Adding Session Timeout to Your React Login Page

Got it, let's implement that session timeout feature with a pre-expiry warning and auto-redirect. Since your LoginForm is a class component, we'll integrate this logic directly into it (you could also extract it into a reusable higher-order component later if you need this across multiple components).

Core Implementation Logic

  • Track user activity (clicks, keystrokes, mouse moves) to reset the timeout timer
  • Show a warning modal a set number of seconds before the session expires
  • Auto-logout and redirect to the initial page if the user doesn't act on the warning
  • Clean up timers and event listeners when the component unmounts to avoid memory leaks

Modified loginform.js Code

import React, { Component } from 'react';
import { connect } from 'react-redux';
import { login } from '../../redux/reducer';
import './LoginForm.css';
import { BrowserRouter as Router, Route, Redirect } from "react-router-dom"

// Adjust these constants to fit your app's requirements
const SESSION_TIMEOUT = 30 * 60 * 1000; // 30 minutes in milliseconds
const WARNING_TIME = 60 * 1000; // 60 seconds before timeout to show warning

class LoginForm extends Component {
  state = {
    showTimeoutWarning: false,
    timeoutTimer: null,
    warningTimer: null,
    isLoggedIn: false // Track login state locally (or use redux state directly)
  };

  componentDidMount() {
    // Start the session timer when the component loads
    this.startSessionTimer();
    // Attach event listeners to detect user activity
    window.addEventListener('mousemove', this.resetSessionTimer);
    window.addEventListener('keydown', this.resetSessionTimer);
    window.addEventListener('click', this.resetSessionTimer);
  }

  componentWillUnmount() {
    // Clean up timers and listeners to prevent memory leaks
    this.clearAllTimers();
    window.removeEventListener('mousemove', this.resetSessionTimer);
    window.removeEventListener('keydown', this.resetSessionTimer);
    window.removeEventListener('click', this.resetSessionTimer);
  }

  startSessionTimer = () => {
    // Clear existing timers first
    this.clearAllTimers();

    // Set timer to show warning before timeout
    const warningTimer = setTimeout(() => {
      this.setState({ showTimeoutWarning: true });
    }, SESSION_TIMEOUT - WARNING_TIME);

    // Set timer for full session timeout
    const timeoutTimer = setTimeout(() => {
      this.handleSessionTimeout();
    }, SESSION_TIMEOUT);

    this.setState({ warningTimer, timeoutTimer });
  };

  resetSessionTimer = () => {
    // If user is active, hide the warning (if visible) and restart timers
    if (this.state.showTimeoutWarning) {
      this.setState({ showTimeoutWarning: false });
    }
    this.startSessionTimer();
  };

  clearAllTimers = () => {
    if (this.state.timeoutTimer) clearTimeout(this.state.timeoutTimer);
    if (this.state.warningTimer) clearTimeout(this.state.warningTimer);
  };

  handleSessionTimeout = () => {
    // Perform logout actions: clear redux state, local storage, etc.
    this.props.dispatch({ type: 'LOGOUT' }); // Update to match your redux logout action
    // Redirect to your initial page (adjust the path as needed)
    this.setState({ isLoggedIn: false });
  };

  handleExtendSession = () => {
    // User chose to keep the session alive
    this.setState({ showTimeoutWarning: false });
    this.resetSessionTimer();
  };

  handleLogoutNow = () => {
    // User chose to logout immediately
    this.handleSessionTimeout();
  };

  render() {
    // Redirect to initial page if session timed out
    if (!this.state.isLoggedIn && this.props.isLoggedIn) {
      return <Redirect to="/" />;
    }

    return (
      <div className="login-form-container">
        {/* Your existing login form content goes here */}
        <form onSubmit={(e) => {
          e.preventDefault();
          // Your existing login logic here
          this.props.login(/* pass your login credentials */);
          this.setState({ isLoggedIn: true });
        }}>
          {/* Add your username/password inputs and submit button here */}
        </form>

        {/* Session Timeout Warning Modal */}
        {this.state.showTimeoutWarning && (
          <div className="timeout-warning-modal">
            <div className="modal-content">
              <h3>Session Expiring Soon</h3>
              <p>Your session will end in {WARNING_TIME / 1000} seconds. Do you want to continue working?</p>
              <button onClick={this.handleExtendSession}>Continue Session</button>
              <button onClick={this.handleLogoutNow}>Logout Now</button>
            </div>
          </div>
        )}
      </div>
    );
  }
}

// Map redux state to props (adjust based on your redux structure)
const mapStateToProps = (state) => ({
  isLoggedIn: state.auth.isLoggedIn
});

export default connect(mapStateToProps, { login })(LoginForm);

Key Things to Adjust

  • Time Values: Tweak SESSION_TIMEOUT and WARNING_TIME to match your app's security requirements.
  • Redux Logout: Update the LOGOUT action in handleSessionTimeout to match your existing redux authentication setup.
  • Styling: Add CSS to the timeout-warning-modal and modal-content classes to make the warning overlay the page and look polished.
  • Redirect Path: Change the <Redirect to="/" /> path to your actual initial page (like /login or /home).
  • Activity Tracking: You can add more event listeners (like scroll or touchstart for mobile) if you want to capture more user interactions.

内容的提问来源于stack exchange,提问作者Lex V

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.26 08:38:59