【问题标题】:ReactJS protected route with API call带有 API 调用的 ReactJS 保护路由
【发布时间】:2019-08-31 20:35:26
【问题描述】:

我正在尝试在 ReactJS 中保护我的路由。 在每个受保护的路由上,我想检查保存在 localStorage 中的用户是否良好。

你可以在下面看到我的路由文件(app.js):

class App extends Component {
    render() {
        return (
            <div>
                <Header />
                <Switch>
                    <Route exact path="/" component={Home} />
                    <Route path="/login" component={Login} />
                    <Route path="/signup" component={SignUp} />
                    <Route path="/contact" component={Contact} />
                    <ProtectedRoute exac path="/user" component={Profile} />
                    <ProtectedRoute path="/user/person" component={SignUpPerson} />
                    <Route component={NotFound} />
                </Switch>
                <Footer />
            </div>
        );
    }
}

我的 protectedRoute 文件:

const ProtectedRoute = ({ component: Component, ...rest }) => (
    <Route {...rest} render={props => (
        AuthService.isRightUser() ? (
            <Component {...props} />
        ) : (
            <Redirect to={{
                pathname: '/login',
                state: { from: props.location }
            }}/>
        )
    )} />
);

export default ProtectedRoute;

还有我的函数isRightUser。当数据对登录的用户无效时,此函数会发送status(401)

async isRightUser() {
    var result = true;
    //get token user saved in localStorage
    const userAuth = this.get();

    if (userAuth) {
        await axios.get('/api/users/user', {
            headers: { Authorization: userAuth }
        }).catch(err => {
            if (!err.response.data.auth) {
                //Clear localStorage
                //this.clear();
            }

            result = false;
        });
    }

    return result;
}

此代码不起作用,我不知道为什么。 也许我需要在调用之前用await 调用我的函数AuthService.isRightUser() 并将我的函数异步?

如何在访问受保护页面之前更新我的代码以检查我的用户?

【问题讨论】:

    标签: javascript reactjs routes async-await react-router-dom


    【解决方案1】:

    我遇到了同样的问题,并通过将受保护的路由设置为有状态的类来解决它。

    我使用的内部开关

    <PrivateRoute 
        path="/path"
        component={Discover}
        exact={true}
    />
    

    我的 PrivateRoute 类如下

    class PrivateRoute extends React.Component {
    
        constructor(props, context) {
            super(props, context);
    
            this.state = {
                isLoading: true,
                isLoggedIn: false
            };
    
            // Your axios call here
    
            // For success, update state like
            this.setState(() => ({ isLoading: false, isLoggedIn: true }));
    
            // For fail, update state like
            this.setState(() => ({ isLoading: false, isLoggedIn: false }));
    
        }
    
        render() {
    
            return this.state.isLoading ? null :
                this.state.isLoggedIn ?
                <Route path={this.props.path} component={this.props.component} exact={this.props.exact}/> :
                <Redirect to={{ pathname: '/login', state: { from: this.props.location } }} />
    
        }
    
    }
    
    export default PrivateRoute;
    

    【讨论】:

    • 完美!最好有一个类和反应状态。
    • 我的登录组件中有一个 axios 调用登录,它返回我的令牌和登录响应。如何使用 PrivateRoute 组件中登录组件的调用?
    • 嗨@bubble-cord。您的登录组件应该是公共路由,因为每个人都应该能够在没有身份验证的情况下进入登录页面。在您的公共登录组件中执行 axios 调用后,您可以使用 this.props.history.push('/main') 将用户重定向到主页
    【解决方案2】:

    当您像在 AuthService.isRightUser() 中那样使用 async 注释函数时,它会返回 Promise 并且您没有相应地处理方法的响应。

    按照您的建议,您可以使用await 调用方法AuthService.isRightUser(),并使用async 注释您传递给render 属性的函数。

    或者您可以使用.then().catch() 而不是三元运算符来处理AuthService.isRightUser() 的响应

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-08-13
      • 1970-01-01
      • 1970-01-01
      • 2021-04-30
      • 1970-01-01
      • 2019-09-13
      • 1970-01-01
      • 2018-03-31
      相关资源
      最近更新 更多