使用react-router-v4对路由进行身份验证

6

我正在尝试为我的DashBoard编写Authentication检查。但是该函数本身没有被调用。有人能给我一些解决方案吗?我正在使用ReactJs进行开发。

这是路由部分:

 <Router>
            <div>
              <Route exact path={"/"} component={Home} />
              <Route path={"/SignUp"} component={SignUp} />
              <Route path={"/SignIn"} component={SignIn} />
              <Route path={"/Dashboard"} component={Dashboard} onEnter={this.requireAuth} />
            </div>
          </Router>

这是函数的代码:
  requireAuth (nextState, replace) {
    console.log("?????????????",this.state.getToken);
    if(!this.state.getToken) {
      replace({pathname: '/'});
    }
  }

如果您正在使用React-router v4,请查看此链接:https://dev59.com/9aPia4cB1Zd3GeqP6O9d#45430656 - Shubham Khatri
我已经进行了更改,如下所示: {requireAuth(); return }} />但是我收到了以下错误提示:bundle.js:6004 警告:您不应在同一路由中使用将被忽略。 - Riya Kapuria
正如错误所示,您不应该同时使用组件和渲染。建议您从渲染属性中呈现Dashboard组件,就像链接答案中建议的那样。 - Shubham Khatri
要不是这个this.requireAuth(),会怎么样? - Shubham Khatri
让我们在聊天中继续这个讨论 - Riya Kapuria
显示剩余2条评论
1个回答

15
react-router v4中,您可以利用render prop与生命周期方法一起使用Route,以替换存在于react-router v3中的onEnter功能。请参见此答案以获取更多详细信息:

onEnter prop in react-router v4

然而,如果您只想在onEnter prop中进行身份验证,那么可以轻松创建一个HOC来完成这个任务。
const RequireAuth = (Component) => { 

    return class App extends Component { 
    
        componentWillMount() { 
            const getToken = localStorage.getItem('token'); 
            if(!getToken) { 
               this.props.history.replace({pathname: '/'}); 
            } 
        } 
        render() { 
           return <Component {...this.props} /> 
        }
    } 

} 

export { RequireAuth }

并像这样使用它

<Route path={"/Dashboard"} component={RequireAuth(Dashboard)}/>

编辑:如果您需要进行网络调用以查找用户是否已验证,那么您可以编写如下的高阶组件:

Edit: 在情况下需要进行网络调用以查找用户是否已验证,您将编写类似于以下方式的 HOC

 const RequireAuth = (Component) => { 

    return class App extends Component { 
        state = {
            isAuthenticated: false,
            isLoading: true
        }
    
        componentDidMount() {
            AuthCall().then(() => {
                this.setState({isAuthenticated: true, isLoading: false});
            }).catch(() => {
                this.setState({isLoading: false});
            })
        } 
        render() { 
           const { isAuthenticated, isLoading } = this.state;
           if(isLoading) {
               return <div>Loading...</div>
           }
           if(!isAuthenticated) {
               return <Redirect to="/login" />
           }
           return <Component {...this.props} /> 
        }
    } 

} 

export { RequireAuth }

更新:

除了 HOC 之外,您还可以选择像 PrivateRoute 组件那样进行操作。

const PrivateRoute = ({component: Component, isAuthenticated, isLoading, ...rest }) => { 
           if(isLoading) {
               return <div>Loading...</div>
           }
           if(!isAuthenticated) {
               return <Redirect to="/login" />
           }
           return <Component {...this.props} /> 
        }
    } 
} 

 export { PrivateRoute };

你可以像这样使用它

  class App extends Component { 
        state = {
            isAuthenticated: false,
            isLoading: true
        }
    
        componentDidMount() {
            AuthCall().then(() => {
                this.setState({isAuthenticated: true, isLoading: false});
            }).catch(() => {
                this.setState({isLoading: false});
            })
        } 
        render() { 
           <Router>
              <div>
                  <Route exact path={"/"} component={Home} />
                  <Route path={"/SignUp"} component={SignUp} />
                  <Route path={"/SignIn"} component={SignIn} />
                  <PrivateRoute path={"/Dashboard"} component={Dashboard} isAuthenticated={this.state.isAuthenticated} isLoading={this.isLoading}/>
               </div>
           </Router>
        }
    } 

   

3
有人是否可以通过React开发者工具直接编辑React状态,将“isAuthenticated:true”和“isLoading:false”进行修改?这样他们就可以访问受保护的路由了。 - JL9
1
如果@JL9这样做,他们会进入视图,但是如果他们向后端发送无效请求,服务器应该以401响应,然后UI将重定向到登录页面。 - Len Joseph

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接