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

如何使用Passport.js、Axios和react-router-dom v6保护前端路由

实现方案

第一步:调整后端接口适配前后端分离场景

你当前使用的successRedirect/failureRedirect是服务端渲染场景的配置,前后端分离场景下需要改为返回JSON响应,同时新增鉴权状态查询接口:

var passport = require("passport");

router.post(
  "/login",
  passport.authenticate("local", {
    session: true, // 开启session存储
    failWithError: true // 鉴权失败返回错误
  }),
  (req, res) => {
    // 鉴权成功返回成功信息
    res.json({
      code: 0,
      message: "登录成功",
      user: req.user
    })
  },
  (err, req, res, next) => {
    // 鉴权失败返回错误
    res.status(401).json({
      code: 1,
      message: "用户名或密码错误"
    })
  }
);

// 新增鉴权状态查询接口
router.get('/check-auth', (req, res) => {
  if (req.isAuthenticated()) {
    return res.json({
      isLoggedIn: true,
      user: req.user
    })
  }
  res.status(401).json({
    isLoggedIn: false
  })
})

module.exports = router;

第二步:前端封装私有路由守卫组件

react-router-dom v6 基于组件化实现路由保护,我们封装通用的私有路由组件,用于包裹所有需要鉴权的页面,新建components/PrivateRoute.js:

import { useState, useEffect } from 'react'
import { Navigate } from 'react-router-dom'
import instance from '../loginAPI.js' // 引入你封装好的带withCredentials的axios实例

const PrivateRoute = ({ children }) => {
  const [isAuth, setIsAuth] = useState(null)
  const [loading, setLoading] = useState(true)

  useEffect(() => {
    const checkAuth = async () => {
      try {
        await instance.get('/check-auth')
        setIsAuth(true)
      } catch (err) {
        setIsAuth(false)
      } finally {
        setLoading(false)
      }
    }
    checkAuth()
  }, [])

  if (loading) return <div>加载中...</div> // 可替换为你的自定义加载组件
  return isAuth ? children : <Navigate to="/login" replace />
}

export default PrivateRoute

第三步:修改路由配置应用鉴权规则

把需要保护的dashboard路由用PrivateRoute组件包裹即可:

import Login from "./pages/Login";
import Dashboard from "./pages/Dashboard";
import PrivateRoute from "./components/PrivateRoute";
import { BrowserRouter as Router, Routes, Route } from "react-router-dom";

function App() {
  return (
    <div>
      <Router>
        <Routes>
          <Route exact path="/" element={<Login />} />
          <Route path="/login" element={<Login />} />
          {/* 受保护路由,只有登录后可以访问 */}
          <Route path="/dashboard" element={
            <PrivateRoute>
              <Dashboard />
            </PrivateRoute>
          } />
        </Routes>
      </Router>
    </div>
  );
}

export default App;

注意事项

后端CORS配置需要满足两个要求:

  • Access-Control-Allow-Credentials 设为 true
  • Access-Control-Allow-Origin 不能设置为通配符*,需要明确填写前端的访问地址(比如http://localhost:3000)

可选优化

如果想避免每次切换路由都发起鉴权查询请求,可以通过React Context、Zustand等全局状态管理方案缓存登录状态,登录成功后更新全局状态,路由守卫优先读取全局状态,不存在时再发起接口查询。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.26 10:06:04