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

React请求出现401 Unauthorized错误:添加Passport中间件后验证失败

问题分析与解决方案

Postman能正常通过身份验证但React端返回401,核心原因是跨域请求时React的fetch默认不会携带会话cookie,而Postman会自动保存并发送登录后的session cookie,导致Passport无法识别React端的登录状态。

1. 后端配置CORS允许凭证传递

首先安装并配置cors中间件,明确允许前端域名跨域请求,同时开启凭证支持:

const cors = require('cors');

// 替换为你的React前端地址,比如http://localhost:3000
const corsOptions = {
  origin: 'http://localhost:3000',
  credentials: true // 允许携带跨域凭证
};

// 注意:该中间件需放在session、passport和路由之前加载
app.use(cors(corsOptions));

同时调整session的cookie配置,适配跨域场景:

const sessionOptions = {
  secret: 'secretgoeshere',
  resave: false,
  saveUninitialized: false,
  cookie: {
    httpOnly: true,
    expires: Date.now() + 1000 * 60 * 60 * 24 * 7,
    maxAge: 1000 * 60 * 60 * 24 * 7,
    sameSite: process.env.NODE_ENV === 'production' ? 'none' : 'lax', // 生产环境设为none,开发环境用lax
    secure: process.env.NODE_ENV === 'production' // 生产环境必须开启secure(依赖HTTPS)
  }
};

2. 前端fetch请求添加凭证配置

修改你的useFetch钩子,强制请求携带凭证:

import { useState, useEffect } from 'react'

const useFetch = (url, options = {}) => {
    const [data, setData] = useState(null)
    const [error, setError] = useState(null)
    const [loading, setLoading] = useState(true)

    useEffect(() => {
        const fetchData = async() => {
            try {
                // 合并默认的凭证配置,确保跨域请求携带cookie
                const fetchOptions = {
                    credentials: 'include',
                    ...options
                }
                const res = await fetch(url, fetchOptions)
                if (!res.ok) throw new Error(`请求失败:${res.status}`)
                const parsedData = await res.json()
                setData(parsedData)
            } catch (e) {
                setError(e);
            } finally {
                setLoading(false)
            }
        }
        fetchData()
        // eslint-disable-line react-hooks/exhaustive-deps
    }, [url, options])

    return { data, error, loading }
}

export default useFetch

3. 检查后端中间件顺序

确保中间件加载顺序严格遵循:
CORS中间件 → Session中间件 → Passport初始化/会话中间件 → 请求体解析中间件(express/json、urlencoded) → 业务路由

你的现有代码中express.json()和urlencoded放在passport之后的顺序没问题,但必须保证CORS中间件在最前面。

验证步骤

  1. 登录后,在React开发者工具的Application→Cookies中确认是否存在后端设置的session cookie
  2. 发起请求时,在Network面板查看Request Headers是否包含Cookie字段
  3. 后端打印req.isAuthenticated()的值,确认是否能正确识别登录状态

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.15 22:45:32