1. ホーム
  2. javascript

[解決済み] React Router 4で認証されたルートを実装するには?

2022-04-27 06:51:35

質問

認証されたルートを実装しようとしていましたが、React Router 4ではこれが動作しないことがわかりました。

<Route exact path="/" component={Index} />
<Route path="/auth" component={UnauthenticatedWrapper}>
    <Route path="/auth/login" component={LoginBotBot} />
</Route>
<Route path="/domains" component={AuthenticatedWrapper}>
    <Route exact path="/domains" component={DomainsIndex} />
</Route>

というエラーが発生します。

警告 を使用するべきではありません。 <Route component><Route children> を同じルートで使用することができます。 <Route children> は無視されます。

その場合、どのように実装するのが正しいのでしょうか?

に表示されます。 react-router (v4) のドキュメントでは、次のようなことを示唆しています。

<Router>
    <div>
    <AuthButton/>
    <ul>
        <li><Link to="/public">Public Page</Link></li>
        <li><Link to="/protected">Protected Page</Link></li>
    </ul>
    <Route path="/public" component={Public}/>
    <Route path="/login" component={Login}/>
    <PrivateRoute path="/protected" component={Protected}/>
    </div>
</Router>

しかし、たくさんのルートをグループ化しながら、これを実現することは可能なのでしょうか?


いろいろ調べた結果、こんなことを思いつきました。

import React, {PropTypes} from "react"
import {Route} from "react-router-dom"

export default class AuthenticatedRoute extends React.Component {
  render() {
    if (!this.props.isLoggedIn) {
      this.props.redirectToLogin()
      return null
    }
    return <Route {...this.props} />
  }
}

AuthenticatedRoute.propTypes = {
  isLoggedIn: PropTypes.bool.isRequired,
  component: PropTypes.element,
  redirectToLogin: PropTypes.func.isRequired
}

でアクションをディスパッチするのは正しいのでしょうか? render() ? それは間違っているように感じます。本当に正しいとは思えません componentDidMount などのフックもあります。

解決方法は?

を使いたくなりますよね。 Redirect コンポーネントを使用します。この問題には、いくつかの異なるアプローチがあります。私が好きなのは、PrivateRouteコンポーネントを用意して、その中に authed props を作成し、その props に基づいてレンダリングします。

function PrivateRoute ({component: Component, authed, ...rest}) {
  return (
    <Route
      {...rest}
      render={(props) => authed === true
        ? <Component {...props} />
        : <Redirect to={{pathname: '/login', state: {from: props.location}}} />}
    />
  )
}

では、あなたの Route は次のようになります。

<Route path='/' exact component={Home} />
<Route path='/login' component={Login} />
<Route path='/register' component={Register} />
<PrivateRoute authed={this.state.authed} path='/dashboard' component={Dashboard} />

まだ迷っている人は、こんな記事を書いたので参考にしてください。 React Router v4で保護されたルートと認証