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

Http-only跨站Cookie无法添加至浏览器的问题求助

Http-only跨站Cookie无法添加至浏览器的问题求助

我现在遇到一个头疼的问题:我用FastAPI做后端、Next.js做前端,登录成功后后端会把refresh和access token作为http-only Cookie返回给前端。我在前端控制台打印响应头的时候,明明能看到Set-Cookie字段里的两个Cookie,但浏览器就是不把它们添加到Cookie存储里,这可太奇怪了!

下面是我的相关配置和代码,麻烦各位大佬帮我看看哪里出问题了:

FastAPI的CORS中间件配置

origins = [
    config.FRONTEND_ORIGIN
]

app.add_middleware(
    CORSMiddleware,
    allow_origins=origins,
    allow_credentials=True,
    allow_methods=["*"],
    allow_headers=["*"]
)

登录接口的后端代码

这个接口负责生成token并设置Cookie:

@auth_router.post("/login", response_model=SuccessLoginResponse, status_code=status.HTTP_200_OK)
async def login(
    response: Response,
    login_data: LoginRequest,
    request: Request,
    session: AsyncSession = Depends(get_session)
):
    IS_PRODUCTION = config.ENV == "production"
    auth_service = get_auth_service(session)
    device_info = request.headers.get("User-Agent", "Unknown Device")

    try:
        tokens = await auth_service.login(login_data, device_info)

        # Set HTTP-only cookies in the response
        response.set_cookie(
            key="refresh_token",
            value=tokens.refresh_token,
            httponly=True,
            max_age=7 * 24 * 60 * 60,  # 7 days
            secure=False,  # Only set to True in production
            samesite="none",
        )

        response.set_cookie(
            key="access_token",
            value=f"Bearer {tokens.access_token}",
            httponly=True,
            max_age=15 * 60,  # 15 minutes
            secure=False,  # Only set to True in production
            samesite="none"
        )

        return {
            "success": True,
            "message": "Login successful"
        }
    except UnauthorizedException as e:
        raise HTTPException(
            status_code=status.HTTP_401_UNAUTHORIZED, detail=str(e)) from e
    except Exception as e:
        print(e)
        raise ValidationException(
            detail={
                "message": "Validation error",
                "errors": str(e),
                "documentation_url": "https://api.example.com/docs"
            }
        ) from e

前端控制台打印的响应头

我用Axios请求后,打印出的响应头里确实有Set-Cookie:

Object [AxiosHeaders] {
  date: 'Mon, 10 Feb 2025 13:47:16 GMT',
  server: 'uvicorn',
  'content-length': '45',
  'content-type': 'application/json',
  'set-cookie': [
    'refresh_token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOjM5LCJleHAiOjE3Mzk4MDAwMzZ9.YnELWecBRiLIDuuZS_RUtfwfdRN--GuL7B5XjvGojKY; HttpOnly; Max-Age=604800; Path=/; SameSite=none',
    'access_token="Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOjM5LCJleHAiOjE3MzkxOTcwMzd9.3eNjdMx88ax9SpWgcyMkaw3sJCteVfrdUqv7jxTfZVU"; HttpOnly; Max-Age=900; Path=/; SameSite=none'
  ]
}

前端的登录请求代码(Server Action)

我已经设置了withCredentials: true,但还是不行:

export async function login(
  formData: FormData
): Promise<{success: boolean; message: string}> {
  const username = String(formData.get("username"));
  const password = String(formData.get("password"));

  try {
    const response = await axios.post(
      `${API_URL}/auth/login`,
      {username, password},
      {
        withCredentials: true,
        headers: {
          "Content-Type": "application/json",
        },
      }
    );

    console.log(response.headers);

    if (response.status !== 200) {
      throw new Error(response.data?.message || "Login failed");
    }

    console.log("Login successful");
    return {success: true, message: "Login successful"};
  } catch (error) {
    if (axios.isAxiosError(error)) {
      console.error("Login error:", error.response?.data || error.message);
      throw new Error(error.response?.data?.message || "Login failed");
    } else {
      console.error("Unexpected error:", error);
      throw new Error("An unexpected error occurred");
    }
  }

  return redirect("/dashboard");
}

各位大佬帮我看看问题出在哪了?感激不尽!

备注:内容来源于stack exchange,提问作者David Essien

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.15 03:18:08