javascript - 如何在reactjs中登录后创建 protected 路由

标签 javascript reactjs

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

App.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;

编辑:codesandbox

最佳答案

成功登录后,也许您将获得用于授权目的的 token 。 因此,成功登录后,您可以将身份验证 token 存储在 cookie 中。

install - npm i universal-cookie --save

登录.js

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";
import Cookies from 'universal-cookie';
const cookies = new Cookies();

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();
      // here you will get auth token in response
      // set token in cookie like cookie.set('token', response.token);
      cookies.set('loggedin', true);

      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; 

之后,在仪表板组件中检查 cookie 中的登录 bool 值(如果存在),然后进行登录并进行身份验证。例如。

仪表板.js

import React, { Component } from "react";
import {Redirect} from 'react-router-dom'
import Cookies from 'universal-cookie';
const cookies = new Cookies();


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

  }
logout=()=>{
  this.setState({loggedIN: false)}
  cookies.set('loggedin', false);
}  
render() {
    // notice here
    if (!cookies.get('loggedin')) {
            return (<Redirect to={'/login'}/>)
        }

    return (
         <div>hello</div>;
        <button onCLick={logout}>Logout</button>  
        )
   }
}
export default Dashboard;

关于javascript - 如何在reactjs中登录后创建 protected 路由,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59373908/

相关文章:

javascript - 如何在 next.config.js 文件中组合几个插件?

CSS 模块覆盖 UI 样式

javascript - 如何将对象数组转换为按属性分组的新对象数组?

css - 你如何有效地将 CSS 网格布局与 React 结合使用?

javascript - 从另一个函数转义/返回一个函数

javascript - 在 dc.js 行图中显示百分比

javascript - string.split() 返回额外的项目(函数)

javascript - 识别 Ext.Component、Ext.Element 和 HTMLElement

reactjs - 在 React Bootstrap 中居中模式标题和按钮

javascript - (类型错误): Cannot read property 'props' of undefined