79773799

Date: 2025-09-24 13:43:24
Score: 1.5
Natty:
Report link

Thanks to @C3roe, I found a solution. I needed to allow credentials in the CORS middleware and and in the fetch calls:

package main

import (
    "context"
    "log"
    "net/http"
    "os"
    "os/signal"
    "syscall"
    "time"


    "github.com/gin-contrib/cors"
    "github.com/gin-contrib/sessions"

    // gormsessions "github.com/gin-contrib/sessions/gorm"
    "github.com/gin-contrib/sessions/cookie"
    "github.com/gin-gonic/gin"
)

func init() {
}

func main() {

    r := gin.Default()

    store := cookie.NewStore([]byte("secret"))
    store.Options(sessions.Options{
        Path:     "/",   // Available across the entire domain
        Domain:   "",    // Adjust to your domain, use an empty string for localhost or omit for default behavior
        MaxAge:   3600,  // Expires in 1 hour
        Secure:   false, // Set to true if serving over HTTPS, false otherwise
        HttpOnly: true,  // Recommended: JavaScript can't access the cookie
    })

    corsConfig := cors.DefaultConfig()
    corsConfig.AllowOrigins = []string{"http://localhost:5173"}
    corsConfig.AllowAllOrigins = false
    corsConfig.AllowCredentials = true

    r.Use(cors.New(corsConfig))
    r.Use(sessions.Sessions("mysession", store))

    r.GET("/inc", func(c *gin.Context) {
        s := sessions.Default(c)
        log.Printf("Session ID: %s", s.ID())
        var count int
        v := s.Get("count")
        if v == nil {
            count = 0
        } else {
            count = v.(int)
            count++
        }

        s.Set("count", count)

        if err := s.Save(); err != nil {
            log.Printf("Error saving session in /inc")
            c.AbortWithError(http.StatusInternalServerError, err)
        }
        c.JSON(200, gin.H{"count": count})
    })

    r.GET("/dec", func(c *gin.Context) {
        s := sessions.Default(c)
        log.Printf("Session ID: %s", s.ID())
        var count int
        v := s.Get("count")
        if v == nil {
            count = 0
        } else {
            count = v.(int)
            count--
        }

        s.Set("count", count)

        if err := s.Save(); err != nil {
            log.Printf("Error saving session in /dec")
            c.AbortWithError(http.StatusInternalServerError, err)
        }
        c.JSON(200, gin.H{"count": count})

    })

    srv := &http.Server{
        Addr:    ":5001",
        Handler: r.Handler(),
    }

    go func() {
        // service connections
        if err := srv.ListenAndServe(); err != nil && err != http.ErrServerClosed {
            log.Fatalf("listen: %s\n", err)
        }
    }()

    quit := make(chan os.Signal, 1)
    signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM)
    <-quit
    log.Println("Shutdown Server ...")

    ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
    defer cancel()
    if err := srv.Shutdown(ctx); err != nil {
        log.Println("Server Shutdown:", err)
    }
    log.Println("Server exiting")
}

And in my javascript calls add:

const init: RequestInit = {
    credentials: 'include'  
};
const resp = await fetch('http://localhost:5001/inc', init);
Reasons:
  • Blacklisted phrase (0.5): Thanks
  • Blacklisted phrase (0.5): I need
  • Long answer (-1):
  • Has code block (-0.5):
  • User mentioned (1): @C3roe
  • Self-answer (0.5):
  • Low reputation (0.5):
Posted by: Brent Parker