Universal Auth Redux 和 React Router
Universal Auth Redux & React Router
我在使用 redux 和 react router 进行身份验证时遇到了一些问题,我希望得到一些关于如何最好地解决我的问题的说明。
我有一个登录组件,在提交时会调度以下操作:
export const loginUser = (creds) => {
return dispatch => {
dispatch(requestLogin(creds))
return fetch('http://127.0.0.1:4000/api/login', {
...
})
.then(res => {
dispatch(receiveLogin())
browserHistory.push('/admin')
...
})
...
}
}
receiveLogin 操作将状态中的 isAuthenticated 标志更新为 true。我的受保护路线具有以下 onEnter 挂钩:
export default (state) => {
return {
path: '/',
component: App,
childRoutes: [
{
path: 'protected',
component: Protected,
...
onEnter(nextState, replaceState) {
const loggedIn = //check state.isAuthenticated
if (!loggedIn) {
replaceState(null, 'login')
}
}
}
]
}
}
如您所见,我将状态作为参数传入。这使我可以从服务器和客户端访问初始状态。但是,在我的登录操作发生后,显然 onEnter 挂钩仍将使用初始状态。
我想知道的是在更新 isAuthenticated 标志后获取当前状态并在我的 onEnter 挂钩中使用它的最佳方法。或者,我的方法是否完全有缺陷,我应该以完全不同的方式来做这件事吗?
我发现在我的应用程序中使用 onEnter 挂钩并不是处理此类身份验证逻辑和连接到 redux 存储的最佳方法。
这里的(几个)陷阱之一是,即使您可以让用户登录到您的 'protected' 路由,如果他们在 'protected' 中注销,他们也永远不会被重定向到 'login' 因为它不会触发 onEnter。
另一种方法是使用高阶组件,请参阅 Dan Abramov 的 post about using them over mixins, and I find them really useful in this context as well. There have been a few gists/example repos out there of how to use them, but I've recently created a library redux-auth-wrapper specifically for this purpose. Its pretty new but I think it might be useful and avoids some dangers when using HOC's incorrectly for auth which can result in infinite-loop-redirects。
使用 HOC 的想法是,它是一种功能,当应用于组件时以某种方式扩展其功能。 redux 的用户很可能熟悉 connect
以通过商店的订阅来增强组件。
在这种情况下,您编写的组件不知道受到 authentication/authorization 的保护,并且在应用 HOC 函数时,将返回具有给定检查的新组件。如果这些通过,则返回包装的组件,否则用户将被重定向到登录的地方(如果是授权问题,则重定向到其他地方)。 HOC 使用 componentWillMount
和 componentWillReceiveProps
生命周期方法来确定是否允许用户查看给定的组件。这允许支持在身份验证更改时重定向组件,即使路由没有。
我还会在此处查看类似策略的示例:https://github.com/joshgeller/react-redux-jwt-auth-example。
这里是一个使用 onEnter 进行身份验证的示例,但我相信它不会处理上述边缘情况:
https://github.com/CrocoDillon/universal-react-redux-boilerplate/blob/master/src/routes.jsx.
我在使用 redux 和 react router 进行身份验证时遇到了一些问题,我希望得到一些关于如何最好地解决我的问题的说明。
我有一个登录组件,在提交时会调度以下操作:
export const loginUser = (creds) => {
return dispatch => {
dispatch(requestLogin(creds))
return fetch('http://127.0.0.1:4000/api/login', {
...
})
.then(res => {
dispatch(receiveLogin())
browserHistory.push('/admin')
...
})
...
}
}
receiveLogin 操作将状态中的 isAuthenticated 标志更新为 true。我的受保护路线具有以下 onEnter 挂钩:
export default (state) => {
return {
path: '/',
component: App,
childRoutes: [
{
path: 'protected',
component: Protected,
...
onEnter(nextState, replaceState) {
const loggedIn = //check state.isAuthenticated
if (!loggedIn) {
replaceState(null, 'login')
}
}
}
]
}
}
如您所见,我将状态作为参数传入。这使我可以从服务器和客户端访问初始状态。但是,在我的登录操作发生后,显然 onEnter 挂钩仍将使用初始状态。
我想知道的是在更新 isAuthenticated 标志后获取当前状态并在我的 onEnter 挂钩中使用它的最佳方法。或者,我的方法是否完全有缺陷,我应该以完全不同的方式来做这件事吗?
我发现在我的应用程序中使用 onEnter 挂钩并不是处理此类身份验证逻辑和连接到 redux 存储的最佳方法。
这里的(几个)陷阱之一是,即使您可以让用户登录到您的 'protected' 路由,如果他们在 'protected' 中注销,他们也永远不会被重定向到 'login' 因为它不会触发 onEnter。
另一种方法是使用高阶组件,请参阅 Dan Abramov 的 post about using them over mixins, and I find them really useful in this context as well. There have been a few gists/example repos out there of how to use them, but I've recently created a library redux-auth-wrapper specifically for this purpose. Its pretty new but I think it might be useful and avoids some dangers when using HOC's incorrectly for auth which can result in infinite-loop-redirects。
使用 HOC 的想法是,它是一种功能,当应用于组件时以某种方式扩展其功能。 redux 的用户很可能熟悉 connect
以通过商店的订阅来增强组件。
在这种情况下,您编写的组件不知道受到 authentication/authorization 的保护,并且在应用 HOC 函数时,将返回具有给定检查的新组件。如果这些通过,则返回包装的组件,否则用户将被重定向到登录的地方(如果是授权问题,则重定向到其他地方)。 HOC 使用 componentWillMount
和 componentWillReceiveProps
生命周期方法来确定是否允许用户查看给定的组件。这允许支持在身份验证更改时重定向组件,即使路由没有。
我还会在此处查看类似策略的示例:https://github.com/joshgeller/react-redux-jwt-auth-example。
这里是一个使用 onEnter 进行身份验证的示例,但我相信它不会处理上述边缘情况: https://github.com/CrocoDillon/universal-react-redux-boilerplate/blob/master/src/routes.jsx.