英文:
Gorilla Session not setting cookie
问题
这是我的Go服务器代码,我不知道为什么我的Gorilla Session不起作用。似乎一切都正常,直到session.save(r, w)。我已经使用Chrome开发工具检查了我的cookie,无论我做什么,都无法出现cookie。我知道我的身份验证已经有问题了,我只需要帮助让会话正常工作,这是我的目标。我不知道为什么这个函数不起作用,有人可以帮忙吗?
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>
英文:
here is the code for my go server, I have no idea why my gorilla session isn't working. it seems like everything works up to session.save(r, w). I already checked my cookies using the chrome dev tools and no matter what I do I can't get a cookie to appear. I know that my authentication is bad already I just need help with getting sessions working which is my goal. I don't know why this function isn't working can anybody help?
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)))
}
Here is my index.html file
<!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
得分: 0
根据session.Save
的文档:
Save
是一个方便的方法,用于保存会话。它与调用store.Save(request, response, session)
相同。在写入响应或从处理程序返回之前,应该调用Save
。
在你的代码中,在调用session.Save
之前,你正在写入响应(fmt.Fprintf(w, "You logged in Succesfully!")
)。这意味着在设置cookie之前,响应(包括包含cookie的标头)已经被写入(因此cookie不会发送到客户端)。
要解决这个问题,只需将fmt.Fprintf(w, "You logged in Succesfully!")
移动到调用session.Save
的下面即可。
英文:
As per the docs for session.Save
>Save is a convenience method to save this session. It is the same as calling store.Save(request, response, session). You should call Save before writing to the response or returning from the handler.
In your code you are writing to the response (fmt.Fprintf(w, "You logged in Succesfully!")
) before calling session.Save
. This means that the response (including the headers that contain cookies) is written before the cookie gets set (so the cookies are not sent to the client).
To fix this just move fmt.Fprintf(w, "You logged in Succesfully!")
underneath the call to session.Save
.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论