使用API​​验证私有路由

时间:2017-09-19 11:00:58

标签: reactjs cookies react-native react-router

我正在尝试验证私人路线。我允许它在允许访问之前检查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部分合并到主路径部分。

由于

2 个答案:

答案 0 :(得分:2)

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

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}/>
  )}/>
)

答案 1 :(得分:1)

每个用户只能欺骗自己的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 ... />
  }