我在Koa服务器上运行ReactRouter。
我的Koa服务器已配置为所有请求都指向'index.html'(使用koa-connect-history-api-fallback),后者又将请求转发给ReactRouter。这一切都很好,除了我无法弄清楚如何进行用户身份验证。
我想保护我的路由,以便用户必须登录才能访问任何路由。问题是我的登录页面是路由之一,这意味着用户必须登录才能访问登录页面!
有没有办法解决这个问题?例如,在我的Koa服务器中,我能以某种方式保护除“/ login”路由之外的所有路由吗?我已经阅读了这个example,它负责ReactRouter中的身份验证,但在客户端进行身份验证对我来说似乎很粗略。我可能会离开基地。
如果你好奇,我正在工作react-redux-starter-kit
答案 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端点。但是这种方法非常宝贵,因为它使用相同的逻辑在客户端和服务器上进行路由,而且非常费力。