我有一个用Golang内置的Web应用程序,由于某种原因,大猩猩会话并不能一直保存cookie数据,只有部分时间可以保存cookie,甚至当我键入新的url时,cookie也会被遗忘。在我登录3次后,cookie将保存3次,但不一致表示存在问题。
我尝试了不同的init()配置和结构,并移动了一些方法来希望即使在调用登录处理程序的get版本时也向用户提供cookie。我到处都有打印语句以打印出发生的情况,因此我可以“实时”跟踪代码的去向。
登录处理程序
func login(w http.ResponseWriter, r *http.Request) {
if debug == true {
fmt.Println("Hit login")
fmt.Println(r.Method)
}
//MAKEING A NEW COOKIE FOR THE USER
session, err := store.Get(r, appCookie)
if err != nil {
fmt.Println("ERROR WITH store.Get", err)
}
//PARSE THE LOGIN PAGE
t, err := template.ParseFiles("auth/login.html")
if err != nil {
fmt.Println("Login Handler parsing error", err)
}
//A CHECK FOR A POST METHOD THAT MIGHT NOT BE NECESSARY ANYMORE
if r.Method != http.MethodPost {
t.Execute(w, nil)
return
}
//READ IN THE PASSWORD ENTERED
pw := r.FormValue("pwd")
//PASSWORD ENCRYPTION
// hash, err := bcrypt.GenerateFromPassword([]byte(pw), bcrypt.MinCost)
// if err != nil {
// log.Println(err)
// }
// if debug == true {
// fmt.Println(r.FormValue("usr"), string(hash))
// }
//ALL OF THE AUTH
if go_dev.Validate(r.FormValue("usr"), string(pw), db) == true {
if debug == true {
fmt.Println("user has been validated")
}
//SET THE USER AS LOGGED IN AND PUT THE USERNAME IN THE COOKIE
session.Values["auth"] = true
session.Values["usr"] = string(r.FormValue("usr"))
if debug == true {
fmt.Println("getUser befor save", session.Values["auth"])
}
//SAVE THE COOKIE TO THE USER'S BROWSER
err := session.Save(r, w)
//SANITY CHECK TO MAKE SURE THE COOKIE WAS ACTUALLY SAVED
session, err := store.Get(r, appCookie)
if err != nil {
fmt.Println("ERROR WITH store.Get", err)
}
if debug == true {
fmt.Println("getUser after save", session.Values["auth"])
}
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
//SEND THEM ALONG TO THEIR USERPAGE
http.Redirect(w, r, "/view/userpage.html", 302)
} else {
if debug == true {
fmt.Println("user has NOT been validated")
}
//EXPLICITLY SET LOGIN STATUS TO FALSE
session.Values["auth"] = false
//SAVE THAT COOKIE TO PERSON'S BROWSER
err := session.Save(r, w)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
//JUST RELOAD THE PAGE
t.Execute(w, nil)
}
}
身份验证功能
func heimdall(w http.ResponseWriter, r *http.Request) bool {
if debug == true {
fmt.Println("Opening the Bifröst")
}
session, _ := store.Get(r, appCookie)
if debug == true {
fmt.Println("Bifröst: ", session, session.Values["auth"])
}
if session.Values["auth"] != true {
session.Values["auth"] = false
err := session.Save(r, w)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
fmt.Println("Error saving cookie")
return false
}
return false
}
session.Values["auth"] = true
return true
}
如何使用heimdall的示例
func ProjectViewHandler(w http.ResponseWriter, r *http.Request) {
if debug == true {
fmt.Println("Hit ProjectViewHandler")
}
//session, _ := store.Get(r, "cookie-name")
if heimdall(w, r) != true {
http.Redirect(w, r, "/login", http.StatusFound)
return
}
pathVariables := mux.Vars(r)
id, _ := strconv.Atoi(string(pathVariables["key"]))
p := go_dev.PopulateProjectPage(id, db)
t, err := template.ParseFiles("/view/project_view.html")
if err != nil {
fmt.Println("project page Handler parsing error", err)
}
t.Execute(w, p)
}
非常感谢您帮助使这些炼狱曲奇始终如一地工作。完整的项目在这里: https://github.com/NikolaasBender/Co-Lab 任何帮助都欢迎。谢谢