更新(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-considered-harmful.html)。
如果有人遇到此问题,并正在寻找推荐的方法来执行此操作,则建议使用高阶组件而不是Mixins。
这是一个HOC的示例,该HOC会在继续操作之前检查用户是否已登录。如果用户未登录,它将把您重定向到登录页面。该组件采用一个名为的道具isLoggedIn
,该道具基本上是一个标志,应用程序可以存储该标志以表示用户是否登录。
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