更新(2019 年 8 月 16 日)
在 react-router v4 和使用 React Hooks 中,这看起来有点不同。让我们从您的App.js
.
export default function App() {
const [isAuthenticated, userHasAuthenticated] = useState(false);
useEffect(() => {
onLoad();
}, []);
async function onLoad() {
try {
await Auth.currentSession();
userHasAuthenticated(true);
} catch (e) {
alert(e);
}
}
return (
<div className="App container">
<h1>Welcome to my app</h1>
<Switch>
<UnauthenticatedRoute
path="/login"
component={Login}
appProps={{ isAuthenticated }}
/>
<AuthenticatedRoute
path="/todos"
component={Todos}
appProps={{ isAuthenticated }}
/>
<Route component={NotFound} />
</Switch>
</div>
);
}
我们正在使用一个Auth
库来检查用户当前是否已通过身份验证。将其替换为您的身份验证检查功能。如果是这样,那么我们将isAuthenticated
标志设置为true
。我们在应用程序首次加载时执行此操作。另外值得一提的是,您可能希望在运行身份验证检查时在您的应用程序上添加一个加载标志,这样您就不会在每次刷新页面时都刷新登录页面。
然后我们将标志传递给我们的路线。我们创建了两种类型的路由AuthenticatedRoute
和UnauthenticatedRoute
。
长AuthenticatedRoute.js
这样。
export default function AuthenticatedRoute({ component: C, appProps, ...rest }) {
return (
<Route
{...rest}
render={props =>
appProps.isAuthenticated
? <C {...props} {...appProps} />
: <Redirect
to={`/login?redirect=${props.location.pathname}${props.location.search}`}
/>}
/>
);
}
它检查是否isAuthenticated
设置为true
。如果是,那么它将呈现所需的组件。如果没有,那么它将重定向到登录页面。
在UnauthenticatedRoute.js
另一方面,看起来是这样的。
export default ({ component: C, appProps, ...rest }) =>
<Route
{...rest}
render={props =>
!appProps.isAuthenticated
? <C {...props} {...appProps} />
: <Redirect to="/" />}
/>;
在这种情况下,如果isAuthenticated
设置为false
,它将呈现所需的组件。如果它设置为 true,它会将您发送到主页。
您可以在我们的指南中找到详细版本 - https://serverless-stack.com/chapters/create-a-route-that-redirects.html。
旧版本
接受的答案是正确的,但React 团队认为 Mixins 是有害的(https://facebook.github.io/react/blog/2016/07/13/mixins-thinked-harmful.html)。
如果有人遇到这个问题并且正在寻找推荐的方法来做到这一点,我建议使用高阶组件而不是 Mixins。
这是一个 HOC 的示例,它将在继续之前检查用户是否已登录。如果用户未登录,那么它会将您重定向到登录页面。该组件采用一个名为 的propsisLoggedIn
,这基本上是您的应用程序可以存储的一个标志,用于表示用户是否已登录。
import React from 'react';
import { withRouter } from 'react-router';
export default function requireAuth(Component) {
class AuthenticatedComponent extends React.Component {
componentWillMount() {
this.checkAuth();
}
checkAuth() {
if ( ! this.props.isLoggedIn) {
const location = this.props.location;
const redirect = location.pathname + location.search;
this.props.router.push(`/login?redirect=${redirect}`);
}
}
render() {
return this.props.isLoggedIn
? <Component { ...this.props } />
: null;
}
}
return withRouter(AuthenticatedComponent);
}
要使用这个 HOC,只需将它包裹在你的路线上。在您的示例中,它将是:
<Route handler={requireAuth(Todos)} name="todos"/>
我在这里的详细分步教程中介绍了这个和其他一些主题 - https://serverless-stack.com/chapters/create-a-hoc-that-checks-auth.html