Add Session Management

Configure session middleware to enable authenticated session management for your application.

Implement a session manager to handle the user's authenticated state. Unlike other Wristband SDKs, which provide built-in session middleware, the Go SDK is unopinionated about session storage — you have full control over how sessions work.

Implement the Session Manager

The SDK defines a SessionManager interface for you to implement. Session data is typically stored in an encrypted cookie — on subsequent requests, the middleware decrypts the cookie and restores the session state. The interface defines three methods your implementation must provide:

type SessionManager interface {
    StoreSession(w http.ResponseWriter, r *http.Request, session *goauth.Session) error
    GetSession(r *http.Request) (*goauth.Session, error)
    ClearSession(w http.ResponseWriter, r *http.Request) error
}
  1. The following code example is a lightweight SessionManager implementation using github.com/gorilla/sessions — use it as a starting point for your own project.

    Run the following command to download the Gorilla sessions library:

go get github.com/gorilla/sessions
  1. Copy this implementation into your project (e.g. session.go):
// session.go

package main

import (
    "encoding/json"
    "errors"
    "net/http"

    "github.com/gorilla/sessions"
    goauth "github.com/wristband-dev/go-auth"
)

const (
    // SessionName is the name used for the session cookie
    SessionName = "session"

    // SessionKey is the key used to store auth data in the session
    SessionKey = "auth_session"
)

// GorillaSessionManager implements the goauth.SessionManager interface
// using gorilla/sessions for session management
type GorillaSessionManager struct {
    store sessions.Store
}

func NewSessionStore(secret []byte, secureCookies bool) goauth.SessionManager {
    store := sessions.NewCookieStore(secret, nil)
    store.Options.Secure = secureCookies
    store.Options.HttpOnly = true
    store.Options.SameSite = http.SameSiteLaxMode
    return &GorillaSessionManager{
        store: store,
    }
}

// StoreSession implements the goauth.SessionManager interface
func (m *GorillaSessionManager) StoreSession(w http.ResponseWriter, r *http.Request, session *goauth.Session) error {
    // Get existing session or create a new one
    sess, err := m.store.Get(r, SessionName)
    if err != nil {
        // If there's an error getting the session, create a new one
        // This can happen if the session was tampered with or is invalid
        sess, err = m.store.New(r, SessionName)
        if err != nil {
             return err
        }
    }

    // Serialize the session to JSON
    sessionJSON, err := json.Marshal(session)
    if err != nil {
        return err
    }

    // Store the serialized session in the session store
    sess.Values[SessionKey] = string(sessionJSON)

    // Save the session
    return sess.Save(r, w)
}

// GetSession implements the goauth.SessionManager interface
func (m *GorillaSessionManager) GetSession(r *http.Request) (*goauth.Session, error) {
    // Get existing session
    sess, err := m.store.Get(r, SessionName)
    if err != nil {
        return nil, err
    }

    // Check if the session contains auth data
    sessionJSON, ok := sess.Values[SessionKey]
    if !ok {
        return nil, errors.New("no auth session found")
    }

    // Parse the serialized session
    var authSession goauth.Session
    err = json.Unmarshal([]byte(sessionJSON.(string)), &authSession)
    if err != nil {
        return nil, err
    }

    return &authSession, nil
}

// ClearSession implements the goauth.SessionManager interface
func (m *GorillaSessionManager) ClearSession(w http.ResponseWriter, r *http.Request) error {
    // Get existing session
    sess, err := m.store.Get(r, SessionName)
    if err != nil {
        // If we can't get the session, that's fine - we wanted to clear it anyway
        return nil
    }

    // Remove the auth data from the session
    delete(sess.Values, SessionKey)

    // Set session to expire
    sess.Options.MaxAge = -1

    // Save the session
    return sess.Save(r, w)
}

Register the Session Manager

After creating your SessionManager implementation, use it to create a Wristband app instance. Provide a 32-character secret as the secret value — generate a secure secret key at https://securepassword.dev.

📘

Disabling Secure Session Cookies in Local Development

By default, session cookies are marked as secure, meaning they're only sent over HTTPS. Most browsers make an exception for localhost, allowing secure cookies over HTTP (e.g., http://localhost) — but some, such as Safari, enforce stricter rules and never send secure cookies over HTTP, even for localhost.

To disable the secure flag for local development, set secure: false in your session options. Be sure to restore secure: true in production to protect session data.

// main.go

package main

import (
  "github.com/wristband-dev/go-auth"
)

func main() {
  cfg := goauth.NewAuthConfig(
    "<WRISTBAND_CLIENT_ID>",
    "<WRISTBAND_CLIENT_SECRET>",
    "<WRISTBAND_APPLICATION_VANITY_DOMAIN>",
  )
  wristbandAuth, err := cfg.WristbandAuth()
  if err != nil {
    // Handle error
  }

  // ADD: Create session manager
  sessionManager := NewSessionStore("<your-generated-secret>", true)

  // ADD: Create the Wristband app with the session manager
  app := wristbandAuth.NewApp(sessionManager)
}
// main.go

package main

import (
  "github.com/wristband-dev/go-auth"
)

func main() {
  cfg := goauth.NewAuthConfig(
    "<WRISTBAND_CLIENT_ID>",
    "<WRISTBAND_CLIENT_SECRET>",
    "<WRISTBAND_APPLICATION_VANITY_DOMAIN>",
    goauth.WithDangerouslyDisableSecureCookies(),
  )
  wristbandAuth, err := cfg.WristbandAuth()
  if err != nil {
    // Handle error
  }

  // ADD: Create session manager
  sessionManager := NewSessionStore("<your-generated-secret>", false)

  // ADD: Create the Wristband app with the session manager
  app := wristbandAuth.NewApp(sessionManager)
}

What’s Next

Next, you'll use the Wristband SDK to create the auth middleware needed to secure your application.

Did this page help you?