Here is the Go code for my sessionized login form
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")
if password == "welcome" && username == "guest" {
session, _ := store.Get(r, "session")
session.Values["authenticated"] = true
err := session.Save(r, w)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
http.Redirect(w, r, "/secret", http.StatusFound)
} else {
fmt.Fprintf(w, "Wrong Login!")
}
}
func secret(w http.ResponseWriter, r *http.Request) {
session, _ := store.Get(r, "session")
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(":3003", context.ClearHandler(http.DefaultServeMux)))
}
For some reason this works when I host the server locally but when I try hosting it on linux Apache Web Server on my Digital Ocean Droplet it stops working. The website even redirects correctly to the secret endpoint but it shows the Forbidden message because the cookie never gets set. Is there some kind of difference that Hosting on Apache makes that is causing this?
Here is the code I used to setup the proxy on my server for Apache, other than that I've kept the server mostly default.
#go
ProxyPass /go http://localhost:3003
ProxyPassReverse /go http://localhost:3003
CodePudding user response:
You are setting store.Options.Domain
to localhost
. The Domain
is used when building the session cookie; meaning that the cookies domain attribute
will be set to localhost
.
As you are hosting your server behind an Apache reverse proxy on a cloud server you will not be accessing it with a localhost
URL (e.g. http://localhost/go
). This means that the domain within your URL will not be localhost
and the cookie will effectively be ignored. See this question for more info.
The quick fix is to leave the Domain
unset e.g.
store.Options = &sessions.Options{
Path: "/",
MaxAge: 3600 * 8,
HttpOnly: true,
}
Note: If you do this the cookie will not be available on subdomains (but that si probably not an issue whilst testing).