Echo Cookie Handling
HTTP cookies are small pieces of data stored on the client's browser. They are commonly used to store user preferences, session information, or track user behavior. In this guide, we'll explore how to handle cookies using the Echo web framework in Go.
Introduction to Cookies in Echo
Cookies allow web applications to store stateful information in the user's browser. The Echo framework provides straightforward methods to set, retrieve, and delete cookies, making state management easier for your web applications.
Cookies consist of:
- Name: The identifier for the cookie
- Value: The actual data stored in the cookie
- Attributes: Additional properties like expiration time, domain, path, security flags, etc.
Setting Cookies in Echo
To set a cookie in Echo, you can use the SetCookie
method of the Context
object.
Basic Cookie Setting
func setCookieHandler(c echo.Context) error {
cookie := new(http.Cookie)
cookie.Name = "username"
cookie.Value = "john_doe"
cookie.Expires = time.Now().Add(24 * time.Hour)
c.SetCookie(cookie)
return c.String(http.StatusOK, "Cookie has been set")
}
In this example, we:
- Create a new cookie using the standard
http.Cookie
struct - Set the name to "username"
- Set the value to "john_doe"
- Set an expiration time of 24 hours from now
- Use Echo's
SetCookie
method to send the cookie to the client
Setting Cookie with More Attributes
func setDetailedCookieHandler(c echo.Context) error {
cookie := new(http.Cookie)
cookie.Name = "session"
cookie.Value = "abc123xyz789"
cookie.Expires = time.Now().Add(7 * 24 * time.Hour)
cookie.Path = "/"
cookie.Domain = "example.com"
cookie.Secure = true
cookie.HttpOnly = true
cookie.SameSite = http.SameSiteStrictMode
c.SetCookie(cookie)
return c.String(http.StatusOK, "Detailed cookie has been set")
}
In this more detailed example, we've set additional cookie attributes:
- Path: Specifies the URL path where the cookie is valid (here, the entire site)
- Domain: Specifies the domain where the cookie is valid
- Secure: When true, the cookie will only be sent over HTTPS connections
- HttpOnly: When true, the cookie cannot be accessed via JavaScript
- SameSite: Controls when cookies are sent with cross-site requests (Strict, Lax, or None)
Retrieving Cookies
To read a cookie that was previously set, use the Cookie
method of the Echo Context
.
func getCookieHandler(c echo.Context) error {
cookie, err := c.Cookie("username")
if err != nil {
return c.String(http.StatusNotFound, "Cookie not found")
}
return c.String(http.StatusOK, "Cookie value: "+cookie.Value)
}
This handler:
- Attempts to retrieve the "username" cookie
- Returns an error message if the cookie doesn't exist
- Returns the cookie value if found
Deleting Cookies
To delete a cookie, set its expiration time to a past date:
func deleteCookieHandler(c echo.Context) error {
cookie := new(http.Cookie)
cookie.Name = "username"
cookie.Value = ""
cookie.Expires = time.Now().Add(-24 * time.Hour) // Set to past time
c.SetCookie(cookie)
return c.String(http.StatusOK, "Cookie has been deleted")
}
Practical Example: User Preferences
Let's implement a more practical example where we use cookies to store user preferences like theme color:
func setThemeHandler(c echo.Context) error {
// Get theme from query parameter
theme := c.QueryParam("theme")
if theme == "" {
theme = "light" // Default theme
}
// Validate theme
validThemes := map[string]bool{"light": true, "dark": true, "blue": true}
if !validThemes[theme] {
return c.String(http.StatusBadRequest, "Invalid theme")
}
// Set the theme cookie
cookie := new(http.Cookie)
cookie.Name = "user_theme"
cookie.Value = theme
cookie.Expires = time.Now().Add(365 * 24 * time.Hour) // Valid for one year
c.SetCookie(cookie)
return c.String(http.StatusOK, "Theme preference saved: "+theme)
}
func getThemeHandler(c echo.Context) error {
cookie, err := c.Cookie("user_theme")
if err != nil {
return c.String(http.StatusOK, "No theme preference found, using default: light")
}
return c.String(http.StatusOK, "Current theme: "+cookie.Value)
}
Authentication Example
Cookies are often used for authentication. Here's a simplified example:
func loginHandler(c echo.Context) error {
username := c.FormValue("username")
password := c.FormValue("password")
// In a real app, you would validate credentials against a database
if username == "admin" && password == "password123" {
// Create a session ID (in real apps, use a secure random generator)
sessionID := "sess_" + fmt.Sprintf("%d", time.Now().UnixNano())
// Store session ID in a cookie
cookie := new(http.Cookie)
cookie.Name = "session_id"
cookie.Value = sessionID
cookie.Expires = time.Now().Add(24 * time.Hour)
cookie.HttpOnly = true // Important for security
c.SetCookie(cookie)
// In a real app, you would also store this session ID in your backend
return c.String(http.StatusOK, "Login successful")
}
return c.String(http.StatusUnauthorized, "Invalid credentials")
}
func authMiddleware(next echo.HandlerFunc) echo.HandlerFunc {
return func(c echo.Context) error {
cookie, err := c.Cookie("session_id")
if err != nil || cookie.Value == "" {
return c.Redirect(http.StatusSeeOther, "/login")
}
// In a real app, validate the session ID against your backend storage
return next(c)
}
}
Complete Route Setup
Here's how you might set up all of these cookie handlers in your Echo application:
package main
import (
"net/http"
"time"
"github.com/labstack/echo/v4"
)
func main() {
e := echo.New()
// Public routes
e.GET("/set-cookie", setCookieHandler)
e.GET("/get-cookie", getCookieHandler)
e.GET("/delete-cookie", deleteCookieHandler)
// Theme preferences
e.GET("/set-theme", setThemeHandler)
e.GET("/get-theme", getThemeHandler)
// Authentication
e.POST("/login", loginHandler)
// Protected routes
private := e.Group("/private")
private.Use(authMiddleware)
private.GET("", func(c echo.Context) error {
return c.String(http.StatusOK, "Welcome to the private area")
})
e.Start(":8080")
}
Cookie Security Best Practices
When working with cookies, keep these security practices in mind:
- HttpOnly: Set this flag for cookies containing sensitive data to prevent XSS attacks
- Secure: Always set this flag for cookies in production environments
- SameSite: Use SameSite=Strict or SameSite=Lax to protect against CSRF attacks
- Expiration: Set reasonable expiration times based on the cookie's purpose
- Data Minimization: Store only necessary information in cookies
- Don't store sensitive data: Never store passwords or other sensitive information in cookies
Summary
Echo provides a simple API for handling cookies in your web applications:
c.SetCookie(cookie)
for setting cookiesc.Cookie(name)
for retrieving cookies- Setting a past expiration date to delete cookies
Cookies are powerful for maintaining state, storing preferences, and handling authentication, but they must be used carefully with proper security considerations.
Additional Resources
Exercises
- Create a language preference system that uses cookies to remember the user's preferred language
- Implement a "Remember Me" login feature using cookies
- Create a shopping cart that persists across page refreshes using cookies
- Build a cookie consent banner that remembers when a user has accepted your cookie policy
- Implement dark mode/light mode toggle functionality using cookies
If you spot any mistakes on this website, please let me know at [email protected]. I’d greatly appreciate your feedback! :)