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

NextJS前端无法通过FastAPI正确设置Cookie的技术问题

解决FastAPI跨域设置Cookie至NextJS前端的问题

问题分析

浏览器将127.0.0.1和localhost判定为不同源,触发跨域Cookie限制:

  • 即使Cookie在开发者工具中显示,跨域场景下前端JS读取权限受限制
  • 刷新后Cookie消失,核心原因是未正确配置Cookie的domain属性,导致浏览器不持久化跨域Cookie

解决方案

一、后端FastAPI配置调整

1. 完善CORSMiddleware

确保明确允许前端源,且开启凭证支持:

from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware

app = FastAPI()

# 精确指定允许的前端源
origins = [
    "http://localhost:3000",
]

app.add_middleware(
    CORSMiddleware,
    allow_origins=origins,
    allow_credentials=True,  # 必须开启,允许携带凭证
    allow_methods=["*"],
    allow_headers=["*"],
)

2. 优化Cookie设置参数

设置Cookie时必须指定domain属性,明确Cookie作用域,同时调整其他参数适配跨域场景:

from fastapi import Response

@app.post("/login")
async def login(response: Response):
    # 执行登录逻辑,生成token...
    response.set_cookie(
        key="access_token",
        value="your_access_token_value",
        httponly=False,  # 允许前端JS读取
        secure=False,  # 开发环境用False,生产环境强制HTTPS时设为True
        samesite="Lax",  # 跨域场景下用Lax或None(None需配合secure=True)
        max_age=3600 * 24 * 7,  # 7天有效期,按需调整
        domain="localhost",  # 关键:指定Cookie作用域为localhost,适配前端地址
        path="/"  # 确保全站路径可访问Cookie
    )
    response.set_cookie(
        key="refresh_token",
        value="your_refresh_token_value",
        httponly=False,
        secure=False,
        samesite="Lax",
        max_age=3600 * 24 * 30,
        domain="localhost",
        path="/"
    )
    return {"status": "success"}

若后端必须使用127.0.0.1:9000,需将domain设为127.0.0.1,同时前端请求地址统一用127.0.0.1:9000。

二、前端NextJS配置调整

1. 统一Axios请求配置

确保withCredentials开启,且请求地址与后端Cookie的domain匹配:

import axios from 'axios';

const api = axios.create({
  baseURL: process.env.NEXT_PUBLIC_API_URL || 'http://localhost:9000', // 统一用localhost,避免混源
  withCredentials: true, // 必须开启,携带Cookie
});

export default api;

2. 客户端组件中读取Cookie

NextJS App Router中,仅客户端组件可访问浏览器Cookie,需添加'use client'指令:

'use client';

import Cookies from 'js-cookie';
import { useDispatch } from 'react-redux';
import api from '@/lib/api';

export default function LoginPage() {
  const dispatch = useDispatch();

  const handleLogin = async () => {
    try {
      await api.post('/login', { username: 'your_username', password: 'your_password' });
      // 读取Cookie并同步到Redux
      const accessToken = Cookies.get('access_token');
      const refreshToken = Cookies.get('refresh_token');
      if (accessToken && refreshToken) {
        dispatch({ 
          type: 'AUTH_SET_TOKENS', 
          payload: { accessToken, refreshToken } 
        });
      }
    } catch (err) {
      console.error('Login failed:', err);
    }
  };

  return <button onClick={handleLogin}>登录</button>;
}

关键注意事项

  • 同源一致性:开发环境下,前后端尽量使用同一域名(如均用localhost),避免浏览器识别为不同源
  • 生产环境要求:生产环境必须启用secure=True,跨域场景下SameSite设为None,且前后端均使用HTTPS
  • Cookie作用域:path="/"确保Cookie在全站可用,避免路径限制导致读取失败
  • App Router限制:服务器组件无法访问浏览器Cookie,所有Cookie操作需在客户端组件中完成

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.23 00:27:25