【问题标题】:Authenticate private routes with API使用 API 验证私有路由
【发布时间】:2018-02-28 03:19:42
【问题描述】:

我正在尝试验证私有路由。我通过在允许访问之前检查 cookie 来使其工作。但是,cookie 可以被欺骗,所以我有一个 API 端点,它接受 cookie 并返回其是否有效。

没有 API 的工作版本:

const PrivateRoute = ({ component: Component, ...rest }) => (
  <Route {...rest} render={props => (
    cookies.get('sessionid') ? (
      <Component {...props}/>
    ) : (
      <Redirect to={{
        pathname: '/',
        state: { from: props.location }
      }}/>
    )
  )}/>
)

ReactDOM.render((
    <Router>
        <Switch>
            <Route exact path="/" component={Login}/>
            <PrivateRoute exact path="/home" component={Home} />
            <PrivateRoute exact path="/upload" component={Upload}/>
            <PrivateRoute exact path="/logout" component={Logout}/>
            <PrivateRoute exact path="/review" component={Review}/>
            <Route component={ NotFound } />
        </Switch>
    </Router>
), document.getElementById('root'))

API 调用的附加代码:

axios.post(process.env.REACT_APP_API_URL+'/account/validate-session', {
    t1_session_id: cookies.get('sessionid')
  })
  .then(function (response) {
    if(response.data.status === "OK"){
        console.log('authenticated go to private route');
    } else {
        console.log('not valid, redirect to index');
    }
  }.bind(this))
  .catch(function (error) {
    console.log('not valid, redirect to index');
  }.bind(this));

问题是我不确定如何将代码的 API 部分合并到主路由部分。

谢谢

【问题讨论】:

    标签: reactjs cookies react-native react-router


    【解决方案1】:

    好吧,我猜你必须为它编写一个包装器组件。让我们试试吧:

    import React, { Component } from 'react';
    import PropTypes from 'prop-types';
    import axios from 'axios';
    
    import YourComponent from './path/to/YourComponent';
    
    class WrapperComponent extends Component {
    
      constructor(props) {
        super(props);
        this.state = {
          isAuth: false
        };
      }
    
      componentDidMount() {
        axios.post(process.env.REACT_APP_API_URL+'/account/validate-session', {
        t1_session_id: cookies.get('sessionid')
        })
        .then(function (response) {
          if(response.data.status === "OK"){
              this.setState({isAuth: true})
          } else {
              this.setState({isAuth: false})
          }
        }.bind(this))
        .catch(function (error) {
          console.log('not valid, redirect to index');
        }.bind(this));
      }
    
      render() {
        return (this.state.isAuth ? <YourComponent /> : null);
      }
    }
    
    export default WrapperComponent;
    

    现在你的路由必须重定向到 WrapperComponent:

    const PrivateRoute = ({ component: WrapperComponent, ...rest }) => (
      <Route {...rest} render={props => (
        <WrapperComponent {...props}/>
      )}/>
    )
    

    【讨论】:

      【解决方案2】:

      每个用户只能欺骗自己的 cookie。同样,用户可以欺骗在其浏览器中运行的整个 JS 代码。因此,调用服务器来验证 cookie 并不会大大减轻您的漏洞。

      相反,您应该信任 JS 代码中的 cookie,并在服务器中需要登录的每个操作中检查 cookie。

      请注意,cookie 不是识别用户的最安全方法,因为它是 CSRF 攻击的对象。您应该使用JWT 或检查referer

      无论如何,如果您决定坚持询问服务器 cookie 是否有效的想法,我会采用 arikanmstf 的回答,除了您应该处理三种情况:auth=true、auth=false 和 auth=null,因为如果我们'还没有从服务器得到答案,我们只想隐藏元素,但如果我们得到否定的答案,我们想重定向用户。

      constructor(props) {
          super(props);
          this.state = {
            isAuth: null
          };
        }
      
      render() {
          if(this.state.isAuth === null) return null;
      
          return (this.state.isAuth ? <YourComponent /> : <Redirect ... />
        }
      

      【讨论】:

        猜你喜欢
        • 2020-07-03
        • 2018-01-18
        • 2020-02-22
        • 2020-01-20
        • 2021-08-06
        • 1970-01-01
        • 2017-12-05
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多