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

Gorilla Session无法设置Cookie问题求助(附相关代码)

Gorilla Session无法生成Cookie的问题排查与修复

我用Go写了服务端代码,现在碰到Gorilla Session不工作的问题——执行到session.Save(r, w)之后,Chrome开发者工具里始终看不到生成的Cookie。我知道认证逻辑还有问题,但现在核心是先解决Session无法正常运行的问题。

服务端Go代码

package main

import (
    "fmt"
    "log"
    "net/http"

    "github.com/gorilla/context"
    "github.com/gorilla/sessions"
)

var store = sessions.NewCookieStore([]byte("super-secret"))

func loginAuthHandler(w http.ResponseWriter, r *http.Request) {
    r.ParseForm()
    username := r.FormValue("username")
    password := r.FormValue("password")
    fmt.Println("username:", username, "password:", password)

    if password == "welcome" && username == "guest" {
        fmt.Fprintf(w, "You logged in Succesfully!")

        session, _ := store.Get(r, "session")
        session.Values["authenticated"] = true
        session.Save(r, w)

        fmt.Println("session started!")
        fmt.Println(session)
    } else {
        fmt.Fprintf(w, "Wrong Login!")
    }
}

func secret(w http.ResponseWriter, r *http.Request) {
    session, _ := store.Get(r, "session")

    fmt.Println(session.Values["authenticated"])

    if auth, ok := session.Values["authenticated"].(bool); !ok || !auth {
        http.Error(w, "Forbidden", http.StatusForbidden)
        return
    }

    fmt.Fprintf(w, "The cake is a lie!")

}

func main() {
    store.Options = &sessions.Options{
        Domain:   "localhost",
        Path:     "/",
        MaxAge:   3600 * 8,
        HttpOnly: true,
    }

    http.HandleFunc("/secret", secret)
    http.HandleFunc("/loginauth", loginAuthHandler)
    http.Handle("/", http.FileServer(http.Dir("public")))
    log.Fatal(http.ListenAndServe(":3002", context.ClearHandler(http.DefaultServeMux)))
}

前端index.html代码

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <meta name="description" content="Go Web App" />

    <link rel="stylesheet" href="index.css">

    <title>Login Form</title>
</head>

<body>
    <div class="container">
        <h1> Login Form </h1>
        <p> user: guest | pass: welcome</p> <br>

        <form action="/loginauth" method="POST">
            <label for="username">Name:</label><br>
            <input type="text" id="username" name="username"> <br>
            <label for="password">Password:</label> <br>
            <input type="password" id="password" name="password"> <br>
            <input type="submit" value="Submit">
        </form>
        
    </div>
    
</body>

</html>

问题修复方案

1. 核心问题:响应内容写入顺序错误

HTTP协议要求响应头(包括Cookie)必须在响应体之前发送。你在调用session.Save(r, w)前,已经用fmt.Fprintf(w, "You logged in Succesfully!")写入了响应体,导致后续的Cookie头无法被浏览器接收。

2. 具体修复步骤

  • 调整代码执行顺序:先完成Session保存操作,再写入响应内容
    修改loginAuthHandler函数:
    if password == "welcome" && username == "guest" {
        // 先获取并保存Session
        session, err := store.Get(r, "session")
        if err != nil {
            http.Error(w, "Failed to get session", http.StatusInternalServerError)
            return
        }
        session.Values["authenticated"] = true
        
        err = session.Save(r, w)
        if err != nil {
            http.Error(w, "Failed to save session", http.StatusInternalServerError)
            return
        }
    
        fmt.Println("session started!")
        fmt.Println(session)
        // 最后写入响应内容
        fmt.Fprintf(w, "You logged in Succesfully!")
    }
    
  • 不要忽略错误:原代码用_忽略了store.Get和session.Save的错误,这会掩盖Session初始化、保存失败等问题,添加错误处理能快速定位问题。

3. 验证修复效果

修复后登录成功,打开Chrome开发者工具的「Application」标签,在「Cookies」下的localhost:3002中即可看到名为session的Cookie,访问/secret接口也能正常返回内容。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.23 13:48:22