package handlers import ( "net/http" "stocksearch/config" "stocksearch/middleware" "stocksearch/services" ) // AuthHandler 로그인/로그아웃 핸들러 type AuthHandler struct { sessionSvc *services.SessionService } // NewAuthHandler 인증 핸들러 초기화 func NewAuthHandler(sessionSvc *services.SessionService) *AuthHandler { return &AuthHandler{sessionSvc: sessionSvc} } // Login POST /login — ID/PW 검증 후 세션 발급 func (h *AuthHandler) Login(w http.ResponseWriter, r *http.Request) { if err := r.ParseForm(); err != nil { http.Error(w, "잘못된 요청입니다.", http.StatusBadRequest) return } id := r.FormValue("id") password := r.FormValue("password") next := r.FormValue("next") if next == "" { next = "/" } // ID/PW 검증 if id != config.App.AdminID || password != config.App.AdminPassword { w.Header().Set("Content-Type", "application/json") w.WriteHeader(http.StatusUnauthorized) _, _ = w.Write([]byte(`{"error":"아이디 또는 비밀번호가 올바르지 않습니다."}`)) return } // 세션 생성 및 쿠키 설정 sessionID := h.sessionSvc.Create() http.SetCookie(w, &http.Cookie{ Name: middleware.SessionCookieName, Value: sessionID, Path: "/", HttpOnly: true, SameSite: http.SameSiteLaxMode, MaxAge: 86400, // 24시간 }) http.Redirect(w, r, next, http.StatusFound) } // CheckSession GET /api/auth/check — 세션 유효성 확인 (200 OK / 401 Unauthorized) func (h *AuthHandler) CheckSession(w http.ResponseWriter, r *http.Request) { cookie, err := r.Cookie(middleware.SessionCookieName) if err != nil || !h.sessionSvc.Validate(cookie.Value) { w.Header().Set("Content-Type", "application/json") w.WriteHeader(http.StatusUnauthorized) _, _ = w.Write([]byte(`{"error":"unauthorized"}`)) return } w.WriteHeader(http.StatusOK) } // Logout POST /logout — 세션 삭제 func (h *AuthHandler) Logout(w http.ResponseWriter, r *http.Request) { if cookie, err := r.Cookie(middleware.SessionCookieName); err == nil { h.sessionSvc.Delete(cookie.Value) } http.SetCookie(w, &http.Cookie{ Name: middleware.SessionCookieName, Value: "", Path: "/", HttpOnly: true, MaxAge: -1, }) w.WriteHeader(http.StatusOK) }