You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React Router v6中如何根据认证状态实现路由重定向?

如何根据用户认证状态实现页面重定向?

我配置了多个不同的路由,以下是App.js代码:

import React from 'react'
import AuthContextProvider from './Contexts/AuthContext'
import RootContextProvider from './Contexts/RootContext'
import { BrowserRouter, Routes, Route } from 'react-router-dom'
import Browse from './Routes/Private/Browse/Browse'
import LandingPage from './Routes/LandingPage'
import Login from './Routes/Login'
import ScrollToTop from './ScrollToTop'
import Home from './Routes/Private/Browse/Outlets/Home'
import TVShows from './Routes/Private/Browse/Outlets/TVShows'
import Latest from './Routes/Private/Browse/Outlets/Latest'
import MyList from './Routes/Private/Browse/Outlets/MyList'
import Movies from './Routes/Private/Browse/Outlets/Movies'
import Title from './Routes/Private/Browse/Title'

function App() {
  return (
    <BrowserRouter>
      <AuthContextProvider>
        <RootContextProvider>
          <Routes>
            // Public routes here
            <Route path='/' element={<LandingPage />} />
            <Route path='/login' element={<Login />} />
            // Public routes here // Private routes here
            <Route path='/browse' element={<Browse />}>
              <Route index element={<Home />} />
              <Route path='tv-shows' element={<TVShows />} />
              <Route path='movies' element={<Movies />} />
              <Route path='latest' element={<Latest />} />
              <Route path='my-list' element={<MyList />} />
            </Route>
            <Route path='movie/:id' element={<Title />} />
            <Route path='tv/:id' element={<Title />} />
            // Private routes here
          </Routes>
          <ScrollToTop />
        </RootContextProvider>
      </AuthContextProvider>
    </BrowserRouter>
  )
}
export default App

我划分了私有路由(Private routes)和公共路由(Public routes),希望根据auth上下文实现以下重定向规则:

  • 当auth === true时:
    • 用户访问任意公共路由时,重定向到/browse
    • 用户访问未找到的路由(not found route)时,重定向到/browse
  • 当auth === false时:
    • 用户访问任意私有路由时,重定向到/login
    • 用户访问未找到的路由时,重定向到/

所有私有路由仅在auth === true时可访问,所有公共路由仅在auth === false时可访问


解决方案

1. 创建路由保护组件

分别创建两个路由包装组件,用来处理不同认证状态下的路由访问权限:

PrivateRoute.jsx(保护私有路由)

import React, { useContext } from 'react'
import { Navigate, Outlet } from 'react-router-dom'
import { AuthContext } from './Contexts/AuthContext'

export default function PrivateRoute() {
  const { auth } = useContext(AuthContext)
  
  // 已认证则渲染子路由/组件,未认证则重定向到登录页
  return auth ? <Outlet /> : <Navigate to="/login" replace />
}

PublicRoute.jsx(限制公共路由仅未认证用户访问)

import React, { useContext } from 'react'
import { Navigate, Outlet } from 'react-router-dom'
import { AuthContext } from './Contexts/AuthContext'

export default function PublicRoute() {
  const { auth } = useContext(AuthContext)
  
  // 未认证则渲染子路由/组件,已认证则重定向到browse页面
  return !auth ? <Outlet /> : <Navigate to="/browse" replace />
}

2. 修改App.js的路由配置

将原有路由按公共/私有分类,用保护组件包裹,并添加404路由处理:

import React, { useContext } from 'react'
import AuthContextProvider from './Contexts/AuthContext'
import RootContextProvider from './Contexts/RootContext'
import { BrowserRouter, Routes, Route, Navigate } from 'react-router-dom'
import Browse from './Routes/Private/Browse/Browse'
import LandingPage from './Routes/LandingPage'
import Login from './Routes/Login'
import ScrollToTop from './ScrollToTop'
import Home from './Routes/Private/Browse/Outlets/Home'
import TVShows from './Routes/Private/Browse/Outlets/TVShows'
import Latest from './Routes/Private/Browse/Outlets/Latest'
import MyList from './Routes/Private/Browse/Outlets/MyList'
import Movies from './Routes/Private/Browse/Outlets/Movies'
import Title from './Routes/Private/Browse/Title'
import PrivateRoute from './PrivateRoute'
import PublicRoute from './PublicRoute'

function App() {
  const { auth } = useContext(AuthContext)

  return (
    <BrowserRouter>
      <AuthContextProvider>
        <RootContextProvider>
          <Routes>
            {/* 公共路由:仅未认证用户可访问 */}
            <Route element={<PublicRoute />}>
              <Route path='/' element={<LandingPage />} />
              <Route path='/login' element={<Login />} />
            </Route>

            {/* 私有路由:仅已认证用户可访问 */}
            <Route element={<PrivateRoute />}>
              <Route path='/browse' element={<Browse />}>
                <Route index element={<Home />} />
                <Route path='tv-shows' element={<TVShows />} />
                <Route path='movies' element={<Movies />} />
                <Route path='latest' element={<Latest />} />
                <Route path='my-list' element={<MyList />} />
              </Route>
              <Route path='movie/:id' element={<Title />} />
              <Route path='tv/:id' element={<Title />} />
            </Route>

            {/* 404路由:根据认证状态重定向 */}
            <Route path='*' element={
              auth ? <Navigate to="/browse" replace /> : <Navigate to="/" replace />
            } />
          </Routes>
          <ScrollToTop />
        </RootContextProvider>
      </AuthContextProvider>
    </BrowserRouter>
  )
}
export default App

3. 确保AuthContext正确提供状态

你的AuthContext需要正确暴露auth状态,示例如下(AuthContext.js):

import React, { createContext, useState, useEffect } from 'react'

export const AuthContext = createContext()

export default function AuthContextProvider({ children }) {
  const [auth, setAuth] = useState(false)

  // 初始化时读取本地存储的认证状态(可根据实际逻辑调整)
  useEffect(() => {
    const isAuthenticated = localStorage.getItem('isAuthenticated') === 'true'
    setAuth(isAuthenticated)
  }, [])

  return (
    <AuthContext.Provider value={{ auth, setAuth }}>
      {children}
    </AuthContext.Provider>
  )
}

关键说明

  • replace属性:重定向后不会在浏览器历史记录中保留原路由,避免用户通过后退按钮回到受限页面
  • Outlet组件:react-router-dom v6中嵌套路由的核心,用于渲染子路由内容
  • 404路由path='*':匹配所有未定义的路由,根据当前认证状态执行对应重定向

内容的提问来源于stack exchange,提问作者Ram Farid

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.09 12:40:22