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
相关产品推荐
相关产品推荐

