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);