From 96fad1a4e78c7209e5a0f3496e8b59d591fbe500 Mon Sep 17 00:00:00 2001 From: nsfisis Date: Sun, 15 Feb 2026 11:12:50 +0900 Subject: refactor(auth): replace JWT authentication with server-side sessions Migrate from stateless JWT tokens to server-side session management backed by PostgreSQL. Sessions are hashed with SHA-256 before storage, cleaned up periodically, and invalidated on logout. This removes the need for JWT_SECRET/COOKIE_SECRET environment variables and the golang-jwt dependency. Co-Authored-By: Claude Opus 4.6 --- backend/main.go | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) (limited to 'backend/main.go') diff --git a/backend/main.go b/backend/main.go index 311c3dd..c1b670a 100644 --- a/backend/main.go +++ b/backend/main.go @@ -73,13 +73,14 @@ func main() { apiGroup := e.Group(conf.BasePath + "api") apiGroup.Use(ratelimit.LoginRateLimitMiddleware(loginRL)) - apiGroup.Use(api.JWTCookieMiddleware) + apiGroup.Use(api.SessionCookieMiddleware(queries)) apiGroup.Use(oapimiddleware.OapiRequestValidator(openAPISpec)) apiHandler := api.NewHandler(queries, gameHub, conf) api.RegisterHandlers(apiGroup, api.NewStrictHandler(apiHandler, nil)) adminHandler := admin.NewHandler(queries, conf) adminGroup := e.Group(conf.BasePath + "admin") + adminGroup.Use(api.SessionCookieMiddleware(queries)) adminHandler.RegisterHandlers(adminGroup) if conf.IsLocal { @@ -104,6 +105,23 @@ func main() { })) } + sessionCleanupCtx, cancelSessionCleanup := context.WithCancel(context.Background()) + defer cancelSessionCleanup() + go func() { + ticker := time.NewTicker(time.Hour) + defer ticker.Stop() + for { + select { + case <-sessionCleanupCtx.Done(): + return + case <-ticker.C: + if err := queries.DeleteExpiredSessions(sessionCleanupCtx); err != nil { + log.Printf("failed to delete expired sessions: %v", err) + } + } + } + }() + go gameHub.Run() if err := e.Start(":80"); err != http.ErrServerClosed { -- cgit v1.3.1