保護されたルートとAuth Guard
wrapper componentsまたはloaderベースのguardを使い、未認証ユーザーをログインページへリダイレクトします。
「保護されたルートとAuth Guard」はCoddyKit上の無料React Academyレッスンです。 これはレッスン3/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはReact Academy学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 React Academyコースには全4レッスンが含まれています。
ルートを保護する理由
ダッシュボード、プロフィール、管理画面などのページは、認証済みのユーザーだけがアクセスできるようにする必要があります。React Router では、ラッパーコンポーネントとローダーベースのガードという2つの方法を利用できます。
認証状態の形
まず、ユーザーがログインしているかどうかをコンポーネントから確認できる認証コンテキストを用意します。
const AuthContext = React.createContext(null);
function AuthProvider({ children }) {
const [user, setUser] = useState(null);
const login = async (creds) => { const u = await apiLogin(creds); setUser(u); };
const logout = () => setUser(null);
return (
<AuthContext.Provider value={{ user, login, logout }}>
{children}
</AuthContext.Provider>
);
}
export const useAuth = () => useContext(AuthContext);ラッパーコンポーネントによるガード
認証状態を確認し、ユーザーが認証されていない場合はログインへリダイレクトする PrivateRoute コンポーネントを作成します。
import { Navigate, Outlet } from 'react-router-dom';
function PrivateRoute() {
const { user } = useAuth();
if (!user) return <Navigate to="/login" replace />;
return <Outlet />;
}
// Usage in router:
{ element: <PrivateRoute />, children: [
{ path: '/dashboard', element: <Dashboard /> },
]}リダイレクト先 URL の保持
ログイン後にユーザーを元のページへ戻せるよう、アクセスしようとした URL を保存します。Navigate コンポーネントの state を介して渡します。
function PrivateRoute() {
const { user } = useAuth();
const location = useLocation();
if (!user) {
return <Navigate to="/login" state={{ from: location }} replace />;
}
return <Outlet />;
}
// In login handler:
const location = useLocation();
const from = location.state?.from?.pathname || '/';
navigate(from, { replace: true });ローダーベースのガード(Data Router)
Data Router API では、ルートの loader に認証チェックを追加します。ユーザーが認証されていない場合は redirect を throw します。
import { redirect } from 'react-router-dom';
function requireAuth() {
const token = localStorage.getItem('token');
if (!token) throw redirect('/login');
return token;
}
const router = createBrowserRouter([
{
path: '/dashboard',
loader: requireAuth,
element: <Dashboard />,
},
]);ロールベースのガード
ガードを拡張してロールも確認します。ユーザーが必要なロールを持っていない場合は、権限のないユーザー向けのページにリダイレクトします。
function AdminRoute() {
const { user } = useAuth();
if (!user) return <Navigate to="/login" replace />;
if (user.role !== 'admin') return <Navigate to="/unauthorized" replace />;
return <Outlet />;
}認証チェック中の読み込み状態
認証状態が非同期に読み込まれる場合(サーバーから取得する場合など)は、チェックが完了するまでスピナーを表示します。これにより、ログインページが一瞬表示されるのを防げます。
function PrivateRoute() {
const { user, isLoading } = useAuth();
if (isLoading) return <Spinner />;
if (!user) return <Navigate to="/login" replace />;
return <Outlet />;
}複数のルートをまとめて保護する
保護対象のすべてのルートを1つの PrivateRoute ラッパーの下にまとめると、各ルートに個別にガードを記述せずに済みます。
const router = createBrowserRouter([
{ path: '/login', element: <Login /> },
{
element: <PrivateRoute />,
children: [
{ path: '/dashboard', element: <Dashboard /> },
{ path: '/profile', element: <Profile /> },
{ path: '/settings', element: <Settings /> },
],
},
]);トークンの有効期限切れへの対応
ガード内またはグローバルインターセプターでトークンの有効期限を確認します。トークンの期限が切れたらユーザーをログアウトさせ、ログインへリダイレクトします。
function isTokenValid(token) {
const payload = JSON.parse(atob(token.split('.')[1]));
return payload.exp * 1000 > Date.now();
}
function requireAuth() {
const token = localStorage.getItem('token');
if (!token || !isTokenValid(token)) throw redirect('/login');
return token;
}リフレッシュトークンのフロー
401 の発生時にリダイレクトする前に、トークンの更新を試みます。更新にも失敗した場合だけログインへリダイレクトします。
async function requireAuth() {
let token = localStorage.getItem('token');
if (!token || isExpired(token)) {
token = await refreshToken();
if (!token) throw redirect('/login');
localStorage.setItem('token', token);
}
return token;
}再読み込み後も認証状態を保持する
認証トークンを localStorage または HttpOnly Cookie に保存します。アプリの読み込み時に、保護されたルートをレンダリングする前に認証状態を復元します。
理解度チェック
React Router でローダーベースの認証ガードを使う場合、認証されていないユーザーをリダイレクトするには何を throw すべきですか?
まとめ
<Outlet /> を使用する PrivateRoute ラッパー、または redirect() を throw するローダーでルートを保護します。ナビゲーション状態に目的の URL を保持し、画面のちらつきを防ぐために読み込み状態を処理します。また、保護対象のルートをまとめて重複を避けます。
よくある質問
「保護されたルートとAuth Guard」レッスンは無料ですか?
はい。「保護されたルートとAuth Guard」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、React Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 React Academyコースには全4レッスンが含まれています。
「保護されたルートとAuth Guard」で何を学びますか?
wrapper componentsまたはloaderベースのguardを使い、未認証ユーザーをログインページへリダイレクトします。 ブラウザで直接実行するハンズオンコードでReact Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。
React Academyを始めるのに経験は必要ですか?
事前経験は必要ありません。CoddyKitのReact Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン3/4です。
「保護されたルートとAuth Guard」レッスンにはどのくらい時間がかかりますか?
ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。
このReact Academyレッスンでコードを書いて実行できますか?
はい。すべてのReact Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。