Skip to main content

Session

Goffee provides a session system that allows you to store and retrieve user-specific data across requests. The session is backed by the cache system (Redis by default) and is tied to an authenticated user via JWT tokens.

The session is available as a built-in feature of the core framework through core.SessionUser. It includes thread-safe methods for managing session data.

How it works​

The session system works in two steps:

  1. Initialization — When a request comes in, call c.GetSession() to create a session instance, then call Init to validate the user's JWT token and cache entry. If valid, the session is loaded from the cache.
  2. Data management — Once initialized, you can set, get, delete, or flush session values that are persisted to the cache.

Initializing the session​

Before you can use the session, you need to initialize it with the current request context:

#file: controllers/sample.go
package controllers

import (
"git.smarteching.com/goffee/core/v2"
)

func Dashboard(c *core.Context) *core.Response {
session := c.GetSession()
authenticated := session.Init(c)

if !authenticated {
return c.Response.SetStatusCode(401).Json(`{"error": "not authenticated"}`)
}

// Session is ready to use
return c.Response.Json(`{"message": "welcome back"}`)
}

The Init method returns true if the session was successfully established. It performs the following checks:

  • Reads the JWT token from the cookie
  • Decodes the token and extracts the user ID
  • Verifies the token against the cached value (keyed by user ID and user agent)
  • If all checks pass, loads any existing session data from the cache

Storing data in the session​

Use Set to store values in the session. The data is automatically saved to the cache. Set returns an error if the value could not be persisted.

session := c.GetSession()

if err := session.Set("theme", "dark"); err != nil {
// handle the error
}
session.Set("language", "en")
session.Set("items_in_cart", 3)

Retrieving data from the session​

Use Get to retrieve values. It returns the value and a boolean indicating whether the key exists.

theme, ok := session.Get("theme")
if ok {
// theme is available
}
itemsInCart, ok := session.Get("items_in_cart")

Deleting a single value​

Use Delete to remove a specific key from the session. It returns the deleted value.

previousValue := session.Delete("items_in_cart")

Clearing the entire session​

Use Flush to delete all session data from the cache. It returns an error if the operation fails.

if err := session.Flush(); err != nil {
// handle the error
}

Getting the authenticated user ID​

Use GetUserID to retrieve the ID of the authenticated user. It returns a uint.

userID := session.GetUserID()

Checking authentication status​

Use IsAuthenticated to check if the session was successfully initialized.

if session.IsAuthenticated() {
// user is authenticated
}

Complete example​

Here is a complete example showing how to use the session in a controller:

#file: controllers/dashboard.go
package controllers

import (
"fmt"

"git.smarteching.com/goffee/core/v2"
)

func Dashboard(c *core.Context) *core.Response {
session := c.GetSession()
if !session.Init(c) {
return c.Response.SetStatusCode(401).Json(`{"error": "not authenticated"}`)
}

// Track page visits
visits, ok := session.Get("page_visits")
count := 0
if ok && visits != nil {
count = c.CastToInt(visits)
}
count++
if err := session.Set("page_visits", count); err != nil {
return c.Response.SetStatusCode(500).Json(`{"error": "could not save session"}`)
}

return c.Response.Json(fmt.Sprintf(
`{"user_id": %d, "page_visits": %d}`,
session.GetUserID(), count,
))
}

Thread safety​

All session operations (Set, Get, Delete, Save, Flush) are protected by a read-write mutex, making them safe for concurrent access.