首页 > 解决方案 > 当 React 上的令牌无效时重定向到登录页面

问题描述

我已经看到多个线程建议在 redux 上使用 Routes,但总的来说,这些示例包含一个公共主页,其中包含登录、注销、访问仪表板等选项。我正在寻找的是允许如果令牌仍然有效,用户可以访问应用程序,否则,它应该重定向到登录页面,这不是应用程序主布局的一部分。让我展示一些代码:

function checkAuth() {
      const token = localStorage.getItem('token');
      if (!token) {
        return false;
      }

      try {
        let payload = decode(token);
        if (payload.exp < new Date().getTime() / 1000) {
          return false;
        }
      } catch (e) {
        return false;
      }
      return true;
    }

    class Main extends Component {
      constructor(props) {
        super(props);
        this.output = this.output.bind(this)
        this.state = { loggedin: false }
      }
      output(evt) {
          this.setState({loggedin: evt})
      }
      Content({output, loggedin})
      {
        if (checkAuth())
          return(<Layout/>);
        if (!loggedin)
          return(<Login func={output}/>);
        else
          return(<Layout/>);
      }
      render() {
        return (
            <this.Content output={this.output} loggedin={this.state.loggedin}/>
         )
      };
    }

首先,我对令牌进行了验证;如果仍然有效,则“内容”函数将返回仪表板,否则将返回登录页面。然后,我向子组件“Login”发送一个函数“output”,这样L​​ogin页面就可以改变“loggedin”标志的状态,这个状态的改变会渲染仪表板。

我的应用组件:

class App extends Component {
  render() {
    return (
      <div className="App">
          <Router>
            <Route path="/" component={Main} />
          </Router>
      </div>
     )
  };
}

它现在按预期工作,但我觉得代码逻辑可以改进。对它的一些意见会有所帮助,我是 React 初学者。我已经在 Github 上发布了代码:Full Code

标签: reactjsreact-router

解决方案


您可以创建一个名为“ProtectedRoute”的组件,在其中执行令牌验证逻辑,如果没有令牌,它会将您重定向到登录页面

// Packages
import React, { Fragment } from 'react';
import { Route, Redirect } from 'react-router-dom';


const ProtectedRoute = ({ component: Component, ...rest }) => {

  const checkValidToken = () => {
    const token = localStorage.getItem('token');
    
    // Validation logic...
  }

  return (
    <Fragment>
      {checkValidToken()
          ? <Route {...rest} render={props => <Component {...rest} {...props} />} />
          : <Redirect to="/auth?mode=login" />
      }
    </Fragment>
  );
}

export default ProtectedRoute

然后按如下方式使用它

class App extends Component {
  render() {
    return (
      <div className="App">
          <Router>
            <ProtectedRoute path="/" component={Main} />
          </Router>
      </div>
     )
  };
}

推荐阅读