服务器端React Router用户身份验证

时间:2016-07-15 03:39:06

标签: reactjs redux react-router koa

我在Koa服务器上运行ReactRouter。

我的Koa服务器已配置为所有请求都指向'index.html'(使用koa-connect-history-api-fallback),后者又将请求转发给ReactRouter。这一切都很好,除了我无法弄清楚如何进行用户身份验证。

我想保护我的路由,以便用户必须登录才能访问任何路由。问题是我的登录页面是路由之一,这意味着用户必须登录才能访问登录页面!

有没有办法解决这个问题?例如,在我的Koa服务器中,我能以某种方式保护除“/ login”路由之外的所有路由吗?我已经阅读了这个example,它负责ReactRouter中的身份验证,但在客户端进行身份验证对我来说似乎很粗略。我可能会离开基地。

如果你好奇,我正在工作react-redux-starter-kit

2 个答案:

答案 0 :(得分:3)

您可以使用装饰器验证顶级组件,例如

// auth.js
import React, {Component} from 'react';
import { connect } from 'react-redux';

export default function(ComposedComponent) {
    class Auth extends Component {
        static contextTypes = {
            router: React.PropTypes.object
        }

        componentWillMount() {
            if (!this.props.authenticated) {
                this.context.router.push('/');
            }
        }

        componentWillUpdate(nextProps) {
            if (!nextProps.authenticated) {
                this.context.router.push('/');
            }
        }

        render() {
            return <ComposedComponent {...this.props} />
        }
    }

    function mapStateToProps(state) {
        return {authenticated: state.auth.authenticated};
    }

    return connect(mapStateToProps)(Auth);
}

@auth
...your component...

如果您有一个auth模块,或者你可以用较少的“reduxy”方式完成它:

function requireAuth(nextState, replace) {
  if (!auth.loggedIn()) {
    replace({
      pathname: '/login',
      state: { nextPathname: nextState.location.pathname }
    })
  }
}

render((
  <Router history={browserHistory}>
    <Route path="/" component={App}>
      <Route path="login" component={Login} />
      <Route path="logout" component={Logout} />
      <Route path="about" component={About} />
      <Route path="dashboard" component={Dashboard} onEnter={requireAuth} />
    </Route>
  </Router>
), document.getElementById('example'))

答案 1 :(得分:1)

在这种情况下,我将负责使用ReactRouter保护路由,并在服务器上使用{ "shell_cmd": "python3 -u \"$file\"", "file_regex": "^[ ]*File \"(...*?)\", line ([0-9]*)", "selector": "source.python", "variants": [ { "name": "Syntax Check", "shell_cmd": "python3 -m py_compile \"${file}\"", } ] } 来确定在任何请求进入时您实际想要呈现/重定向的路由。

重要的是,当请求到达Koa服务器时,您通过一些身份验证中间件运行它,该中间件能够告诉您用户是否经过身份验证及其角色。然后,您希望此信息反映在Redux存储中。您可以使用如下所示的初始状态生成商店:

match

,或者甚至更好的是你可以在减价机为你做商店的商店发送一个动作。

现在,当您在服务器上创建路由(在您的商店中传递)时,React路由器将确切地知道什么是好的,什么不是。也就是说,如果您通过选中{ user: { authenticated: true, role: 'admin' } } 来保护包含onEnter的路由,那么在服务器上调用user.authenticated将尊重该路由,并将重定向返回到match之类的内容。 onEnter示例可能如下所示:

/login

您可以在const ensureLoggedIn = (nextState, replace) => { if (!store.getState().user.authenticated)) { replace('/login'); } }; 中捕获该重定向,这是redirectLocation回调中的参数。阅读有关匹配here的所有信息。然后,您可以将服务器match与新位置一起使用。

当然,这种类型的路由保护只是方便,您需要合法地保护包含敏感信息的API端点。但是这种方法非常宝贵,因为它使用相同的逻辑在客户端和服务器上进行路由,而且非常费力。