From 3fb182c2717ad96d1755adc43bef347ed67e2416 Mon Sep 17 00:00:00 2001 From: tolelom <98kimsungmin@naver.com> Date: Tue, 24 Feb 2026 15:11:34 +0900 Subject: [PATCH] =?UTF-8?q?feat:=20=ED=9A=8C=EC=9B=90=EA=B0=80=EC=9E=85=20?= =?UTF-8?q?API=20=EC=B6=94=EA=B0=80=20(POST=20/api/auth/register)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Register 서비스 메서드 추가 (중복 아이디 체크, bcrypt 해시, role: user로 생성) - Register 핸들러 추가 (빈값, 6자 미만 비밀번호 유효성 검사) - /api/auth/register 라우트 등록 (public) Co-Authored-By: Claude Sonnet 4.6 --- internal/auth/handler.go | 20 ++++++++++++++++++++ internal/auth/service.go | 15 +++++++++++++++ routes/routes.go | 1 + 3 files changed, 36 insertions(+) diff --git a/internal/auth/handler.go b/internal/auth/handler.go index a0c8364..7fbcba2 100644 --- a/internal/auth/handler.go +++ b/internal/auth/handler.go @@ -10,6 +10,26 @@ func NewHandler(svc *Service) *Handler { return &Handler{svc: svc} } +func (h *Handler) Register(c *fiber.Ctx) error { + var req struct { + Username string `json:"username"` + Password string `json:"password"` + } + if err := c.BodyParser(&req); err != nil { + return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{"error": "잘못된 요청입니다"}) + } + if req.Username == "" || req.Password == "" { + return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{"error": "아이디와 비밀번호를 입력해주세요"}) + } + if len(req.Password) < 6 { + return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{"error": "비밀번호는 6자 이상이어야 합니다"}) + } + if err := h.svc.Register(req.Username, req.Password); err != nil { + return c.Status(fiber.StatusConflict).JSON(fiber.Map{"error": err.Error()}) + } + return c.Status(fiber.StatusCreated).JSON(fiber.Map{"message": "회원가입이 완료되었습니다"}) +} + func (h *Handler) Login(c *fiber.Ctx) error { var req struct { Username string `json:"username"` diff --git a/internal/auth/service.go b/internal/auth/service.go index 99f3542..6389d63 100644 --- a/internal/auth/service.go +++ b/internal/auth/service.go @@ -77,6 +77,21 @@ func (s *Service) DeleteUser(id string) error { return s.repo.Delete(id) } +func (s *Service) Register(username, password string) error { + if _, err := s.repo.FindByUsername(username); err == nil { + return fmt.Errorf("이미 사용 중인 아이디입니다") + } + hash, err := bcrypt.GenerateFromPassword([]byte(password), bcrypt.DefaultCost) + if err != nil { + return fmt.Errorf("비밀번호 처리에 실패했습니다") + } + return s.repo.Create(&User{ + Username: username, + PasswordHash: string(hash), + Role: RoleUser, + }) +} + func (s *Service) EnsureAdmin(username, password string) error { if _, err := s.repo.FindByUsername(username); err == nil { return nil // 이미 존재하면 스킵 diff --git a/routes/routes.go b/routes/routes.go index 9117c2e..32ede24 100644 --- a/routes/routes.go +++ b/routes/routes.go @@ -18,6 +18,7 @@ func Register( // Auth a := api.Group("/auth") + a.Post("/register", authH.Register) a.Post("/login", authH.Login) a.Post("/logout", middleware.Auth, authH.Logout)