提问者:小点点

如何在React路由器中保护路由


我正在使用React with Node&;express和Authentication with passport和passport local,我想知道如何在React中保护路由,我的意思是我只想在用户通过身份验证时显示组件,否则我想要它在登录页面上重定向。

在我的情况下,我想保护Notes路由,我正在尝试的方法根本不起作用。。。

我的React代码

import React from 'react';
import { Switch, Route, Redirect } from 'react-router-dom';
import axios from 'axios';

import Register from './Components/Register';
import Login from './Components/Login';
import Notes from './Components/Notes';


function App () {


  //Function to check authentication from server
  const checkAuth = () => {
    axios.get('http://localhost:8000/notes', { withCredentials : true })
    .then(res => res.data)
  }


  return (
    <Switch>
      <Route exact path='/' component={Register} />
      <Route exact path='/login' component={Login} />

      <Route exact path='/notes' render={() => {
         return checkAuth()? (
             <Notes />
           ) : (
             <Redirect to="/login" />
           )
      }} />
    </Switch>
  );
};

export default App;

和我的服务器端代码

//Notes Page
router.get('/notes', (req, res) => {
    if(req.isAuthenticated()) {
        res.send(req.user.email);
    }else{
        res.send(false);
    }
};

共3个答案

匿名用户

替换下面的代码

<Route exact path='/notes' render={() => {
         checkAuth()? (
             <Notes />
           ) : (
             <Redirect to="/login" />
           )
      }} />

请使用此代码

<Route exact path="/notes">{checkAuth ? <Notes /> : <Redirect to="/login" />}</Route>

匿名用户

通过“服务器请求”检查登录状态需要时间!然后考虑创建一个带有State!的类,下面给出一个例子:

import React, { Component } from 'react';
import { Switch, Route, Redirect } from 'react-router-dom';
import axios from 'axios';

import Register from './Components/Register';
import Login from './Components/Login';
import Notes from './Components/Notes';


class App extends Component {

    state = {
        login: false
    }

    componentDidMount() {
        //Function to check authentication from server
        this.checkAuth()
    }

    checkAuth = () => {
        // API request to check if user is Authenticated
        axios.get('http://localhost:8000/notes', { withCredentials : true })
        .then( res => {
            console.log(res.data);
            // API response with data => login success!
            this.setState({
                login: true
            });
        });
    }


    render() {

        let protectedRoutes = null;
        if(this.state.login === true) {
            // if login state is true then make available this Route!
            protectedRoutes = <Route exact path='/notes' component={Notes} />
        }

        return (
            <Switch>
                <Route exact path='/' component={Register} />
                <Route exact path='/login' component={Login} />
                { protectedRoutes }
            </Switch>
        );
    }
};

export default App;

我希望这个例子对你有用。

匿名用户

由于函数checkauth进行网络调用可能无法及时返回正确的值进行呈现,因此您应该做的是创建一个状态,说明用户是否经过身份验证,并让checkauth更新该状态。

const [authenticated, updateAuthenticated] = useState(false);

。。。更新您的checkAuth以更新已验证的状态

//Function to check authentication from server
const checkAuth = () => {
    axios.get('http://localhost:8000/notes', { withCredentials : true })
    .then(res => updateAuthenticated(res.data)); // double check to ensure res.data contains the actual value returned
  }

。。。更新您的呈现以使用状态

<Route exact path='/notes' render={() => {
     return (authenticated ? 
         (<Notes />)
        : 
         (<Redirect to="/login" />)
       )
  }} />

。。。使用这种方法,您还可以将useStation中的默认值设置为true或false,并确定是否是您的服务器端代码造成了麻烦

。。。dont for get调用位于顶部的UseEffect中的CheckAuth

useEffect(()=>{
    checkAuth()
},[])