diff --git a/cookies.go b/cookies.go index 4e51470..9830099 100644 --- a/cookies.go +++ b/cookies.go @@ -19,6 +19,7 @@ import ( "os" "strconv" "strings" + "time" ) // ErrValueTooLong indicates that the cookie value exceeds the allowed length limit. @@ -84,9 +85,8 @@ func GetCookie(r *http.Request) (UserCookie, error) { } // SetCookie sets an encrypted cookie with a user's email and token, using gob encoding for data serialization. +// The Secure flag is controlled by the COOKIE_SECURE environment variable (defaults to true, set to false for local HTTP development). func SetCookie(w http.ResponseWriter, email string, token string) error { - // Initialize a User struct containing the data that we want to store in the - // cookie. var err error // check if template engine is enable @@ -124,15 +124,36 @@ func SetCookie(w http.ResponseWriter, email string, token string) error { return err } + // Derive cookie MaxAge from JWT_LIFESPAN_MINUTES (default: 1440 min = 1 day) + maxAge := 1440 * 60 // default 1 day in seconds + lifetimeStr := os.Getenv("JWT_LIFESPAN_MINUTES") + if lifetimeStr != "" { + lifetime, parseErr := strconv.Atoi(lifetimeStr) + if parseErr == nil { + maxAge = lifetime * 60 // convert minutes to seconds + } + } + + // Determine if the cookie should have the Secure flag. + // Set COOKIE_SECURE=false (or "0", "f") in your .env for local development over HTTP. + // Defaults to true for production safety. + cookieSecureStr := os.Getenv("COOKIE_SECURE") + if cookieSecureStr == "" { + cookieSecureStr = "true" + } + cookieSecure, _ := strconv.ParseBool(cookieSecureStr) + // Call buf.String() to get the gob-encoded value as a string and set it as // the cookie value. cookie := http.Cookie{ Name: "goffee", Value: buf.String(), Path: "/", - MaxAge: 3600, + MaxAge: maxAge, + Expires: time.Now().Add(time.Duration(maxAge) * time.Second), HttpOnly: true, SameSite: http.SameSiteLaxMode, + Secure: cookieSecure, } // Write an encrypted cookie containing the gob-encoded data as normal.