首页 > 解决方案 > reactjs登录后如何创建受保护的路由

问题描述

我对反应很陌生。我正在尝试创建一个项目,用户必须登录才能访问页面,并且我想保护一个只有在成功登录后才能访问的路由。我不想要花哨的用户管理或类似的东西,所以请不要推荐 context 或 redux。我只希望我的 localhost:3000/editor 只有在登录后才能访问,如果有人试图在没有登录的情况下访问 /editor,那么他们将被重定向到登录页面。所以像 isAuthenicated: true/false 这样的事情我相信在我的情况下会很好,但我不确定如何在我的 webapp 中传递它。如果有人可以告诉我如何做到这一点,我会非常高兴?我创建了这个但有很多错误

应用程序.js

import React, {useState} from "react";
import { BrowserRouter as Router, Switch, Route, Link } from "react-router-dom";
import "./App.css";
import Login from "./login";
import Dashboard from "./dashboard";
function App() {
 const [loggedIN, setLoggedIN]=useState(false);
  let privateRoutes = null;
   if(loggedIN){
      privateRoutes =(
        <Route path="/dashboard" component={Dashboard} />
      )}  
  return (
  <>  

  <Router>
      <div className="container">
        <nav className="navbar navbar-expand-lg navheader">
          <div className="collapse navbar-collapse">
            <ul className="navbar-nav mr-auto">
              <li className="nav-item">
                <Link to={"/Login"} className="nav-link">
                  Login
                </Link>
              </li>
            </ul>
          </div>
        </nav>
        <br />
        <Switch>
          <Route exact path="/login" component={Login} />
          {privateRoutes}
        </Switch>
      </div>
    </Router>
  </>);
}
export default App;

登录.js

import React, { Component } from "react";
import MuiThemeProvider from "material-ui/styles/MuiThemeProvider";
import AppBar from "material-ui/AppBar";
import RaisedButton from "material-ui/RaisedButton";
import TextField from "material-ui/TextField";
import { Link } from "react-router-dom";
import "./loginForm.css";
class Login extends Component {
  constructor(props) {
    super(props);
    this.state = {
      email: "",
      password: ""
    };
    this.onchange = this.onchange.bind(this);
  }
  onchange(e) {
    this.setState({ [e.target.name]: e.target.value });
  }
  performLogin = async () => {
    var body = {
      password: this.state.password,
      email: this.state.email
    };
    const options = {
      method: "POST",
      headers: {
        "Content-Type": "application/json",
        Accept: "application/json"
      },
      body: JSON.stringify(body)
    };
    const url = "/api/authenticate";
    try {
      const response = await fetch(url, options);
      const text = await response.text();
      if (text === "redirect") {
        this.props.setState({loggedIN: true})
        this.props.history.push(`/dashboard`);
      } else {
        console.log("login failed");
        window.alert("login failed");
      }
    } catch (error) {
      console.error(error);
    }
  };

  render() {
    return (
      <>
        <div className="loginForm">
          <MuiThemeProvider>
            <TextField
              hintText="Enter your Email"
              floatingLabelText="Email"

              onChange={(event, newValue) => this.setState({ email: newValue })}
            />

            <br />
            <TextField
              type="password"
              hintText="Enter your password"
              floatingLabelText="password"

              onChange={(event, newValue) =>
                this.setState({ password: newValue })
              }
            />

            <br />
            <RaisedButton
              label="Submit"
              primary={true}
              style={style}
              onClick={event => this.performLogin(event)}
            />

          </MuiThemeProvider>
        </div>
      </>
    );
  }
}
const style = {
  margin: 15
};
export default Login;

编辑器页面

import React, { Component } from "react";

class Dashboard extends Component {
constructor(props) {
    super(props);

  }
logout=()=>{
  this.setState({loggedIN: false)}
}  
render() {
    return (
         <div>hello</div>;
        <button onCLick={logout}>Logout</button>  
        )
   }
}
export default Dashboard;

编辑:代码框

标签: javascriptreactjs

解决方案


我认为您在这里有错误,或者最好更改它

let privateRoutes = null;
   if(loggedIN){
      privateRoutes =(
        <Route path="/dashboard" component={Dashboard} />
      )} 

将其更改为

let privateRoutes =()=>{
    if(loggedIN){
      return(
               <Route path="/dashboard" component={Dashboard} />
            )
     }
}

但你不需要这个!你可以使用渲染路线

<Route path="/home" render={() => {
      if(loggedIN){
      return(<Dashboard ...props/>)
     }else{
             return(<Login ...props/>)
          }
 }} />

请注意,登录后 ((loggedIN)) 将在 App.js 中为真,它将自动转到仪表板

参考:https ://reacttraining.com/react-router/web/api/Route/render-func


推荐阅读