React 上である API に対してログイン状態でなければログインページへ自動でリダイレクトされ、ログイン状態でなければ移動できないルーティング(認証が API のみの場合、URL 直叩きによって具体的なデータ抜きの React 上のページを見れる様なコードを生みやすいです)を実現します。
この処理はログインページが React で作られている場合にログインページ以外のページを骨組みだけでも外部に見せたくない、という要求を満たすのに便利です。認証処理が必要な環境が web ページならばログインページだけを React と別に静的ページで用意し、React を用いるページへのアクセスに認証が必要、とする実現方法もあります。
これは次で実装できます。
/**
* ログイン済みならば true,そうでないならば false を返す関数
* @return {Promise<boolean>}
*/
const getIsAuthenticated = async () => {
try{
// API にアクセスして認証済みか確認するなど、何か認証を確認する適当な非同期処理
const response = await BaseRepository.post('is-auth', {/** トークン等の認証状態を示すデータ */});
return !!response.data.success;
}catch(err){
return false;
}
};
/**
* ログイン済みか否かをチェックするフック
* @return {{isLoading: boolean, setAuthenticated: React.Dispatch<React.SetStateAction<boolean>>, isAuthenticated: boolean}}
*/
const useAuthChecker = () => {
const [isLoading, setLoading] = React.useState(true);
const [isAuthenticated, setAuthenticated] = React.useState(false);
// アプリ(厳密にはこのフックを使っているコンポーネント)がマウントされた際に一度だけログイン済みか否かを確認
React.useEffect( () => {
getIsAuthenticated().then(auth => {
// ログイン済みか否かの確認が終われば、それを state にセット
setAuthenticated(auth);
setLoading(false);
});
},[])
return {
isLoading,
isAuthenticated,
setAuthenticated,
}
}
/**
* ログイン済みか否かでルーティングを切り替えるルーター
* @return {JSX.Element}
*/
const AuthRouter = () => {
const {isLoading, isAuthenticated, setAuthenticated} = useAuthChecker();
// ログイン済みか否かを確認している間は具体的な画面を表示せず、ローディングのみを表示
if(isLoading){
return (<div>通信中...</div>)
}
// ログイン済みか否かを確認できたならば、認証済み用ルーティングかログインページかの分岐を処理する
return isAuthenticated ? (
<AppFrame logout={() => setAuthenticated(false)}>{/* ページの大枠。ログアウトボタンを含むコンポーネントを想定 */}
<Switch>
<Route path={'/hoge'}><div>ログインした状態のみのルーティング例</div></Route>
<Route path="*"><NotFound/></Route>{/* NotFound は 404 ページ用コンポーネント */}
</Switch>
</AppFrame>
) : (
<Switch>
<Route path="/login"><LoginPage login={()=>setAuthenticated(true)}/></Route>{/* ログインページ */}
<Redirect to={{pathname: '/login', state: {from: location}}}/>{/* 認証がまだの状態で/login 以外のページへ移動しようとした場合、/loginへリダイレクト */}
</Switch>
)
}
// React 共通の DOM へのマウント
const App = () => <Router><AuthRouter/></Router>;
import ReactDOM from 'react-dom';
ReactDOM.render(<App />, document.getElementById('root'));
getIsAuthenticated が認証済みかの API を叩くリポジトリ的関数、useAuthChecker が自動で認証チェックをするためのロジック、AuthRouter が認証状態で姿を変える画面です。
例では isAuthenticated と三項演算子によって認証状態でのみルーティングを変化させていますが、ユーザー種別などもっと多い分岐にも使えます。分岐を多くする場合はオブジェクトを使ってどの定数の状態のユーザがどのルーティングを使うなどのマッピングを行うと整理しやすいです。
【JavaScript】オブジェクトリテラルをswitch文的に扱う – 株式会社シーポイントラボ | 浜松のシステム・RTK-GNSS開発