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

React无法从Go服务器获取Cookie会话数据问题

问题诊断与修复方案

核心问题分析

你的问题核心出在跨域Cookie共享配置和前端请求凭据传递上,与会话库本身无关,以下是具体问题和修复步骤:


1. 统一CORS Origin配置

后端三个Handler的Access-Control-Allow-Origin不一致:

  • HandleAuth、HandleAuthCallback用的是http://127.0.0.1:5173
  • HandleCurrentUser用的是http://localhost:5173

浏览器会将127.0.0.1和localhost判定为不同源,直接导致Cookie无法跨域传递。统一改成同一个地址,比如全部使用http://127.0.0.1:5173,也可以用环境变量统一管理该配置。

修复后的HandleCurrentUser CORS头:

w.Header().Set("Access-Control-Allow-Origin", "http://127.0.0.1:5173")

2. 配置会话Cookie的跨域属性

无论使用scs还是gorilla/sessions,都需要给Cookie设置正确的跨域参数,确保前端请求能携带Cookie:

  • SameSite: 设置为SameSiteLaxMode(开发环境可临时用SameSiteNoneMode,但需配合Secure属性)
  • HttpOnly: 建议开启,防范XSS攻击,不影响Cookie传递
  • Domain: 本地环境设置为127.0.0.1
  • Path: 设置为/,确保所有路径都能访问会话

以gorilla/sessions为例,初始化store时添加配置:

store := sessions.NewCookieStore([]byte("your-secret-key"))
store.Options = &sessions.Options{
    Path:     "/",
    Domain:   "127.0.0.1",
    MaxAge:   86400 * 7, // 7天有效期
    HttpOnly: true,
    SameSite: http.SameSiteLaxMode,
    // 生产环境必须开启Secure,开发环境可暂时关闭
    // Secure:   true,
}

3. 前端Fetch请求带上凭据

默认情况下,fetch不会向跨域后端发送Cookie,必须添加credentials: 'include'参数:

修复后的前端代码:

useEffect(() => {
    fetch('http://127.0.0.1:3080/user', {
        method: 'GET',
        credentials: 'include', // 关键:携带Cookie
    })
        .then(response => {
            if (!response.ok) {
                throw new Error(response.statusText);
            }
            return response.text();
        })
        .then(data => {
            setUser(data);
            console.log(data);
        })
        .catch(error => console.error(error));
}, []);

4. AuthCallback后跳回前端

当前HandleAuthCallback返回文本,用户停留在后端回调页面,会话Cookie仅在该页面上下文生效。应在会话保存成功后跳回前端页面,确保后续前端请求能携带Cookie:

修改HandleAuthCallback的最后一行:

// 替换原有的fmt.Fprintf
http.Redirect(w, r, "http://127.0.0.1:5173/", http.StatusFound)

5. 修正会话不存在的错误处理

HandleCurrentUser中,若session无用户或类型转换失败,返回500错误不合理,应返回401未授权,同时需判断用户是否为空:

修复后的HandleCurrentUser:

func (h Handler) HandleCurrentUser(w http.ResponseWriter, r *http.Request) {
    w.Header().Set("Access-Control-Allow-Origin", "http://127.0.0.1:5173")
    w.Header().Set("Access-Control-Allow-Headers", "Content-Type")
    w.Header().Set("Access-Control-Allow-Methods", "GET")
    // 允许跨域携带凭据,必须配置
    w.Header().Set("Access-Control-Allow-Credentials", "true")

    session, err := store.Get(r, "session")
    if err != nil {
        http.Error(w, err.Error(), http.StatusInternalServerError)
        return
    }
    user, ok := session.Values["user"].(string)
    if !ok || user == "" {
        // 未找到用户,返回401未授权
        http.Error(w, "用户未找到", http.StatusUnauthorized)
        return
    }
    w.Header().Set("Content-Type", "text/plain")
    w.Write([]byte(user))
}

验证步骤

  1. 重启后端与前端服务
  2. 点击Login按钮完成GitHub OAuth授权
  3. 授权完成后会自动跳回前端,此时前端fetch请求会携带会话Cookie
  4. 查看浏览器控制台的Network请求,确认Request Headers中包含Cookie: session=xxx
  5. 检查Response是否返回正确的用户名

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.25 00:32:34