I have a web app built in Golang and for some reason gorilla sessions doesn't save cookie data all the time, only some of the time does the cookie save and even then when I type in a new url the cookie is forgotten. After I hit login about 3 times the cookie will save but the inconsistency means that there is something wrong.
I have tried different init() configurations and structs and moving around some methods to hopefully get the user a cookie even when the get version of the login handler is called. I have print statements everywhere to print out what has happened and so i can trace where the code went in "real time".
The login handler
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)
}
}
The auth checking function
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
}
an example of how heimdall is used
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)
}
Help getting these infernal cookies to work consistently would be greatly appreciated. The full project is here: https://github.com/NikolaasBender/Co-Lab Any and all help is welcome. Thank you