package main import ( "encoding/json" "net/http" "strings" "github.com/gin-contrib/sessions" "github.com/gin-gonic/gin" ) // Middleware injects form data from session into context for templates func SessionHandlerMiddleware() gin.HandlerFunc { return func(c *gin.Context) { session := sessions.Default(c) raw := session.Get("form_data") form := map[string]string{} if raw != nil { if data, ok := raw.(string); ok { _ = json.Unmarshal([]byte(data), &form) } // clear after first use session.Delete("form_data") _ = session.Save() } // make available in context c.Set("form", form) // Set message in context when there is one available in the session message := session.Get("message") c.Set("mes", message) session.Delete("message") _ = session.Save() c.Next() } } // SaveForm stores submitted POST form data into the session func SaveForm(c *gin.Context) { session := sessions.Default(c) form := map[string]string{} for key, values := range c.Request.PostForm { if len(values) > 0 { form[key] = values[0] } } if b, err := json.Marshal(form); err == nil { session.Set("form_data", string(b)) _ = session.Save() } } // SaveForm stores submitted POST form data into the session func SetMessage(c *gin.Context, message string) { session := sessions.Default(c) session.Set("message", message) _ = session.Save() } func setSessionCookie(c *gin.Context, token string) { // Very long-lived cookie for one year maxAge := 365 * 24 * 60 * 60 httpOnly := true secure := strings.HasPrefix(baseURL, "https://") sameSite := http.SameSiteLaxMode c.SetCookie("session", token, maxAge, "/", cookieDomain, secure, httpOnly) // Workaround to set SameSite explicitly via header c.Header("Set-Cookie", (&http.Cookie{Name: "session", Value: token, Path: "/", Domain: cookieDomain, MaxAge: maxAge, Secure: secure, HttpOnly: httpOnly, SameSite: sameSite}).String()) } func getSessionUser(c *gin.Context) *User { cookie, err := c.Cookie("session") if err != nil || cookie == "" { return nil } var s Session if err := db.Preload("User").Where("token = ?", cookie).First(&s).Error; err != nil { return nil } return &s.User }