From 0ad19562a558126fc31ff6c3af9c978d60052b2a Mon Sep 17 00:00:00 2001 From: tolelom <98kimsungmin@naver.com> Date: Mon, 16 Mar 2026 21:40:51 +0900 Subject: [PATCH] =?UTF-8?q?fix:=20Internal=20API=20=EB=9D=BC=EC=9A=B0?= =?UTF-8?q?=ED=8A=B8=EB=A5=BC=20apiLimiter=EB=B3=B4=EB=8B=A4=20=EB=A8=BC?= =?UTF-8?q?=EC=A0=80=20=EB=93=B1=EB=A1=9D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fiber는 라우트를 등록 순서대로 매칭하므로, /api/internal이 /api 그룹 뒤에 있으면 apiLimiter가 먼저 적용됨. 순서를 변경하여 Rate Limit 우회. Co-Authored-By: Claude Opus 4.6 (1M context) --- routes/routes.go | 68 +++++++++++++++++++++++++----------------------- 1 file changed, 36 insertions(+), 32 deletions(-) diff --git a/routes/routes.go b/routes/routes.go index 8e5c89a..3b5973f 100644 --- a/routes/routes.go +++ b/routes/routes.go @@ -35,6 +35,42 @@ func Register( // Default 1MB body limit for API routes; upload endpoints are excluded apiBodyLimit := middleware.BodyLimit(1*1024*1024, "/api/download/upload") + + // ── Internal API (Rate Limit 제외, API Key 인증만) ────────────── + // 반드시 /api 그룹보다 먼저 등록해야 apiLimiter를 우회함 + internalApi := app.Group("/api/internal", apiBodyLimit, middleware.ServerAuth) + + // Internal - Boss Raid + br := internalApi.Group("/bossraid") + br.Post("/entry", brH.RequestEntry) + br.Post("/start", brH.StartRaid) + br.Post("/complete", middleware.IdempotencyRequired, brH.CompleteRaid) + br.Post("/fail", brH.FailRaid) + br.Get("/room", brH.GetRoom) + br.Post("/validate-entry", brH.ValidateEntryToken) + br.Post("/register", brH.RegisterServer) + br.Post("/heartbeat", brH.Heartbeat) + br.Post("/reset-room", brH.ResetRoom) + br.Get("/server-status", brH.GetServerStatus) + + // Internal - Auth + internalAuth := internalApi.Group("/auth") + internalAuth.Post("/verify", authH.VerifyToken) + + // Internal - Player + internalPlayer := internalApi.Group("/player") + internalPlayer.Get("/profile", playerH.InternalGetProfile) + internalPlayer.Post("/save", playerH.InternalSaveGameData) + + // Internal - Chain + internalChain := internalApi.Group("/chain") + internalChain.Post("/reward", middleware.IdempotencyRequired, chainH.InternalGrantReward) + internalChain.Post("/mint", middleware.IdempotencyRequired, chainH.InternalMintAsset) + internalChain.Get("/balance", chainH.InternalGetBalance) + internalChain.Get("/assets", chainH.InternalGetAssets) + internalChain.Get("/inventory", chainH.InternalGetInventory) + + // ── Public API (Rate Limit 적용) ──────────────────────────────── api := app.Group("/api", apiLimiter, apiBodyLimit) // Auth @@ -105,36 +141,4 @@ func Register( p.Get("/profile", playerH.GetProfile) p.Put("/profile", playerH.UpdateProfile) - // ── Internal API (Rate Limit 제외, API Key 인증만) ────────────── - internalApi := app.Group("/api/internal", apiBodyLimit, middleware.ServerAuth) - - // Internal - Boss Raid - br := internalApi.Group("/bossraid") - br.Post("/entry", brH.RequestEntry) - br.Post("/start", brH.StartRaid) - br.Post("/complete", middleware.IdempotencyRequired, brH.CompleteRaid) - br.Post("/fail", brH.FailRaid) - br.Get("/room", brH.GetRoom) - br.Post("/validate-entry", brH.ValidateEntryToken) - br.Post("/register", brH.RegisterServer) - br.Post("/heartbeat", brH.Heartbeat) - br.Post("/reset-room", brH.ResetRoom) - br.Get("/server-status", brH.GetServerStatus) - - // Internal - Auth - internalAuth := internalApi.Group("/auth") - internalAuth.Post("/verify", authH.VerifyToken) - - // Internal - Player - internalPlayer := internalApi.Group("/player") - internalPlayer.Get("/profile", playerH.InternalGetProfile) - internalPlayer.Post("/save", playerH.InternalSaveGameData) - - // Internal - Chain - internalChain := internalApi.Group("/chain") - internalChain.Post("/reward", middleware.IdempotencyRequired, chainH.InternalGrantReward) - internalChain.Post("/mint", middleware.IdempotencyRequired, chainH.InternalMintAsset) - internalChain.Get("/balance", chainH.InternalGetBalance) - internalChain.Get("/assets", chainH.InternalGetAssets) - internalChain.Get("/inventory", chainH.InternalGetInventory) }