From 26ead17e4c3682a93f64cca646b291b7ce6b195d Mon Sep 17 00:00:00 2001 From: nsfisis Date: Fri, 20 Feb 2026 21:58:17 +0900 Subject: feat(auth): add structured logging for login success and failure Add ClientIPMiddleware to extract client IP into context.Context, enabling structured log output with username, IP, and failure reason for login attempts. Change failed login log level from Error to Warn as authentication failures are expected events. Co-Authored-By: Claude Opus 4.6 --- backend/api/handler.go | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'backend/api/handler.go') diff --git a/backend/api/handler.go b/backend/api/handler.go index 74ffcf8..4105efc 100644 --- a/backend/api/handler.go +++ b/backend/api/handler.go @@ -51,9 +51,11 @@ func (r postLoginCookieResponse) VisitPostLoginResponse(w http.ResponseWriter) e func (h *Handler) PostLogin(ctx context.Context, request PostLoginRequestObject) (PostLoginResponseObject, error) { username := request.Body.Username password := request.Body.Password + ip := GetClientIPFromContext(ctx) + userID, err := h.auth.Login(ctx, username, password) if err != nil { - slog.Error("login failed", "error", err) + slog.Warn("login failed", "username", username, "ip", ip, "reason", err.Error()) var msg string if errors.Is(err, auth.ErrForteeLoginTimeout) { msg = "ログインに失敗しました" @@ -87,6 +89,8 @@ func (h *Handler) PostLogin(ctx context.Context, request PostLoginRequestObject) return nil, echo.NewHTTPError(http.StatusInternalServerError, err.Error()) } + slog.Info("login succeeded", "username", username, "user_id", dbUser.UserID, "ip", ip) + return postLoginCookieResponse{ cookie: http.Cookie{ Name: "albatross_session", -- cgit v1.3.1