TypeUtilities

Cookies

Cookie handling utilities for managing HTTP cookies in Squirrel Framework.

Cookie Type Definition

type Cookie struct {
    Name   string // name of the cookie
    Value  string // cookie value
    Quoted bool   // indicates whether the Value was initially Quoted or not
    
    Path       string    // optional
    Domain     string    // optional
    Expires    time.Time // optional
    RawExpires string    // optional
    
    // MaxAge = 0; means no 'MaxAge' attributes set
    // MaxAge < 0; means delete cookie now, equivalently MaxAge = 0
    // MaxAge > 0; means Max-Age attribute present and available in seconds
    MaxAge   int
    Secure   bool
    HttpOnly bool
    SameSite SameSite
    Raw      string
    Unparsed []string // Raw text of unparsed attribute-value pairs
}

Cookie Functions

FormatSetCookie()

Serializes a cookie struct into a string for the Set-Cookie header.

func FormatSetCookie(c Cookie) string

ParseCookieHeader()

Parses the Cookie header from incoming requests.

func ParseCookieHeader(header string) []cookies.Cookie

Working with Cookies

Setting Cookies

How to set cookies in responses using the Response.SetCookie() method.

server.Post("/login", func(req *Request, res *Response) {
    // Simulate login validation
    body, _ := req.ReadBodyAsString()
    
    // Create session cookie
    sessionCookie := &cookies.Cookie{
        Name:     "session_id",
        Value:    "user_session_" + generateSessionID(),
        Path:     "/",
        MaxAge:   86400, // 24 hours
        HttpOnly: true,  // Prevent XSS attacks
        Secure:   true,  // HTTPS only
        SameSite: cookies.SameSiteStrictMode,
    }
    
    // Create user preference cookie
    themeCookie := &cookies.Cookie{
        Name:   "user_theme",
        Value:  "dark",
        Path:   "/",
        MaxAge: 86400 * 30, // 30 days
    }
    
    // Set cookies
    res.SetCookie(sessionCookie)
    res.SetCookie(themeCookie)
    
    res.JSON(map[string]string{
        "message": "Login successful",
        "sessionId": sessionCookie.Value,
    })
    res.Send()
})

func generateSessionID() string {
    return fmt.Sprintf("%d", time.Now().UnixNano())
}

Reading Cookies

How to read cookies from requests using the Request.GetCookie() method.

server.Get("/profile", func(req *Request, res *Response) {
    // Get session cookie
    sessionCookie := req.GetCookie("session_id")
    if sessionCookie == nil {
        res.SetStatus(401)
        res.JSON(map[string]string{
            "error": "No session found. Please login.",
        })
        res.Send()
        return
    }
    
    // Get user preferences
    themeCookie := req.GetCookie("user_theme")
    theme := "light" // default
    if themeCookie != nil {
        theme = themeCookie.Value
    }
    
    // Get language preference
    langCookie := req.GetCookie("user_lang")
    language := "en" // default
    if langCookie != nil {
        language = langCookie.Value
    }
    
    res.JSON(map[string]interface{}{
        "sessionId": sessionCookie.Value,
        "preferences": map[string]string{
            "theme": theme,
            "language": language,
        },
        "message": "Profile data retrieved",
    })
    res.Send()
})

Deleting Cookies

How to delete cookies by setting MaxAge to -1.

server.Post("/logout", func(req *Request, res *Response) {
    // Delete session cookie
    sessionCookie := &cookies.Cookie{
        Name:     "session_id",
        Value:    "",
        Path:     "/",
        MaxAge:   -1, // Delete immediately
        HttpOnly: true,
        Secure:   true,
    }
    
    // Delete theme cookie
    themeCookie := &cookies.Cookie{
        Name:   "user_theme",
        Value:  "",
        Path:   "/",
        MaxAge: -1,
    }
    
    res.SetCookie(sessionCookie)
    res.SetCookie(themeCookie)
    
    res.JSON(map[string]string{
        "message": "Logged out successfully",
    })
    res.Send()
})

Cookie Security Best Practices

Important security considerations when working with cookies.

// Secure cookie configuration
func createSecureCookie(name, value string) *cookies.Cookie {
    return &cookies.Cookie{
        Name:     name,
        Value:    value,
        Path:     "/",
        MaxAge:   3600, // 1 hour
        HttpOnly: true,  // Prevent XSS - JavaScript cannot access
        Secure:   true,  // HTTPS only
        SameSite: cookies.SameSiteStrictMode, // CSRF protection
    }
}

// Authentication middleware using secure cookies
func authMiddleware(next HandlerFunc) HandlerFunc {
    return func(req *Request, res *Response) {
        sessionCookie := req.GetCookie("secure_session")
        
        if sessionCookie == nil {
            res.SetStatus(401)
            res.JSON(map[string]string{
                "error": "Authentication required",
            })
            res.Send()
            return
        }
        
        // Validate session (implement your own validation logic)
        if !isValidSession(sessionCookie.Value) {
            // Delete invalid cookie
            invalidCookie := &cookies.Cookie{
                Name:     "secure_session",
                Value:    "",
                Path:     "/",
                MaxAge:   -1,
                HttpOnly: true,
                Secure:   true,
            }
            res.SetCookie(invalidCookie)
            
            res.SetStatus(401)
            res.JSON(map[string]string{
                "error": "Invalid session",
            })
            res.Send()
            return
        }
        
        next(req, res)
    }
}

func isValidSession(sessionID string) bool {
    // Implement your session validation logic
    // Check against database, cache, etc.
    return sessionID != "" && len(sessionID) > 10
}

// Cookie security checklist:
// ✅ Use HttpOnly for sensitive cookies
// ✅ Use Secure flag for HTTPS
// ✅ Set appropriate SameSite policy
// ✅ Use reasonable MaxAge values
// ✅ Validate cookie values
// ✅ Delete cookies on logout

SameSite Cookie Policies

Understanding different SameSite policies for CSRF protection.

// SameSite policy examples

// Strict: Cookie only sent with same-site requests
strictCookie := &cookies.Cookie{
    Name:     "strict_session",
    Value:    "session_value",
    SameSite: cookies.SameSiteStrictMode,
    // Best for: Authentication cookies, sensitive data
    // Limitation: Not sent on external links to your site
}

// Lax: Cookie sent with same-site requests and top-level navigation
laxCookie := &cookies.Cookie{
    Name:     "lax_session",
    Value:    "session_value",
    SameSite: cookies.SameSiteLaxMode,
    // Best for: General session cookies
    // Balance between security and usability
}

// None: Cookie sent with all requests (requires Secure flag)
noneCookie := &cookies.Cookie{
    Name:     "tracking_cookie",
    Value:    "tracking_value",
    SameSite: cookies.SameSiteNoneMode,
    Secure:   true, // Required when SameSite=None
    // Best for: Third-party integrations, embedded content
    // Security risk: Vulnerable to CSRF attacks
}

// Default (no SameSite specified): Browser default behavior
defaultCookie := &cookies.Cookie{
    Name:  "default_cookie",
    Value: "default_value",
    // Browser will apply its default policy (usually Lax)
}