[解決済み] react-routerでルートへのアクセスを制限する方法は?
質問
react-routerで特定のルートへのアクセスを制限する方法をご存知の方はいらっしゃいますか?特定のルートへのアクセスを許可する前に、ユーザーがログインしているかどうかをチェックしたいのです。簡単なことだと思ったのですが、ドキュメントを見てもやり方がよくわかりません。
これは、私が定義する場所で設定すべきものですか?
<Route>
コンポーネントを定義する際に設定すべきものでしょうか、それともコンポーネント ハンドラ内で処理すべきものでしょうか?
<Route handler={App} path="/">
<NotFoundRoute handler={NotFound} name="not-found"/>
<DefaultRoute handler={Login} name="login"/>
<Route handler={Todos} name="todos"/> {/* I want this to be restricted */}
</Route>
どのように解決するのですか?
更新情報(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
. これは、アプリが最初にロードされるときに行います。また、ページを更新するたびにログインページが表示されないように、認証チェックが実行されている間はアプリにローディングサインを追加するとよいでしょう。
次に、このフラグをルーティングに渡します。2種類のルーティングを作成します。
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 .
古いバージョン
受け入れられた答えは正しいのですが、Mixinは有害であると考えられています( https://facebook.github.io/react/blog/2016/07/13/mixins-considered-harmful.html )とReactチームによって考えられています。
もし誰かがこの質問に出くわして、これを行うための推奨される方法を探しているなら、私はMixinの代わりにHigher Order Componentsを使うことをお勧めします。
ここに、処理を進める前にユーザーがログインしているかどうかをチェックする 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
関連
-
[解決済み] 配列から特定の項目を削除するにはどうすればよいですか?
-
[解決済み] jQueryで要素が非表示になっているかどうかを確認するには?
-
[解決済み] JavaScriptで文字列が部分文字列を含むかどうかを確認する方法は?
-
[解決済み] あるJavaScriptファイルを他のJavaScriptファイルにインクルードするにはどうすればよいですか?
-
[解決済み] GUID / UUIDの作成方法
-
[解決済み] Reactルータを使ったプログラムによるナビゲーション
-
[解決済み] React-routerのURLを更新したり、手動で書き込んだりするとうまくいかない
-
[解決済み】別のウェブページにリダイレクトするにはどうすればいいですか?
-
[解決済み] JavaScript で範囲を作成する - 奇妙な構文
-
[解決済み] オブジェクトの配列からReactコンポーネントをレンダリングする
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み] JavaScriptで次の要素/前の要素を取得しますか?
-
[解決済み] 文字列がすべて同じ部分文字列で構成されているかどうかを調べるにはどうすればよいですか?
-
[解決済み] reactのrender関数でdynamic hrefを作成するには?
-
[解決済み] JavaScriptでの大文字小文字を区別しない正規表現
-
[解決済み] AngularJS - ngRepeatフィルタリングされた結果の参照を取得する方法
-
[解決済み] モデルフェッチ時に1をtrueに、0をfalseに変換する方法
-
[解決済み] CORS: 認証モードは 'include' です。
-
[解決済み] javascriptでオプションのパラメータを扱う
-
[解決済み] querySelectorAllがない場合、ライブラリを使用せずに属性で要素を取得する?
-
[解決済み] jQueryのバージョン1、バージョン2、バージョン3の違いは何ですか?[クローズド]