From 3b1719666fc4674cba1fcfdf8ebbebfb280ffb9e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EB=AF=BC=ED=97=8C?= Date: Tue, 7 Jul 2026 14:36:37 +0900 Subject: [PATCH] =?UTF-8?q?refactor(auth):=20popup=20API=20=EB=A6=AC?= =?UTF-8?q?=EB=B7=B0=20=EA=B0=9C=EC=84=A0=20+=20=EB=AC=B4=ED=86=A0?= =?UTF-8?q?=ED=81=B0=20=ED=85=8C=EC=8A=A4=ED=8A=B8=20=EB=B3=B4=EA=B0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 원작성자 컨벤션 대조 리뷰 반영. - README 엔드포인트 표에 logout·popup/status·popup/hide 추가(누락분 포함) - user_crud: get_hide_service_info 의 불필요한 bool() 캐스트 제거 (execute 가 단일 컬럼 select 에서 이미 스칼라 반환 — get_supplier_name 과 동일) - account: popup 라우터를 me 뒤로 이동(로그인→계정→토큰→내정보→팝업 흐름) - test_auth: test_popup_hide_without_token 추가(me 섹션과 무토큰 가드 대칭) Co-Authored-By: Claude Fable 5 --- backend/README.md | 3 +++ backend/crud/user_crud.py | 2 +- backend/router/v1/auth/account.py | 28 ++++++++++++++-------------- backend/tests/test_auth.py | 5 +++++ 4 files changed, 23 insertions(+), 15 deletions(-) diff --git a/backend/README.md b/backend/README.md index 943f6bb..0187e46 100644 --- a/backend/README.md +++ b/backend/README.md @@ -46,7 +46,10 @@ backend/ | POST | `/v1/auth/create` | 계정 생성 (pw bcrypt 해시) | | POST | `/v1/auth/login` | 로그인, access/refresh 토큰 발급 | | POST | `/v1/auth/refresh_token` | access 토큰 재발급 (refresh 필요) | +| POST | `/v1/auth/logout` | 로그아웃, 저장 토큰 폐기 (access 토큰 필요) | | GET | `/v1/auth/me` | 내 정보 (access 토큰 필요) | +| GET | `/v1/auth/popup/status` | 팝업 '안내 보지 않기' 저장 상태 (access 토큰 필요) | +| POST | `/v1/auth/popup/hide` | 팝업 안내 보지 않기 영구 저장 (access 토큰 필요) | ## 실행 / 테스트 ```bash diff --git a/backend/crud/user_crud.py b/backend/crud/user_crud.py index 8d708bf..21eb679 100644 --- a/backend/crud/user_crud.py +++ b/backend/crud/user_crud.py @@ -217,7 +217,7 @@ class UserCRUD(IUserCRUD): return err_type, None if len(row_list) != 1: return ErrorType.DB_INVALID_KEY, None - return ErrorType.SUCCESS, bool(row_list[0]) + return ErrorType.SUCCESS, row_list[0] except Exception as ex: LOG.e_no_callstack(ex) return ErrorType.DB_RUN_FAILED, None diff --git a/backend/router/v1/auth/account.py b/backend/router/v1/auth/account.py index 80828cc..b894c65 100644 --- a/backend/router/v1/auth/account.py +++ b/backend/router/v1/auth/account.py @@ -65,6 +65,20 @@ async def logout(user_info: UserInfo = Depends(IsValidAccessToken), service: Aut return RemoveNoneResponse(await service.logout(user_info)) +@router.get( + path="/me", + response_model=Res_Me, + summary="내 정보 (보호된 엔드포인트)", + description="access 토큰 검증(validator) 후 su_id DB 존재/활성 + 저장 토큰 대조를 service 에서 확인해 반환한다.", +) +async def me( + user_info: UserInfo = Depends(IsValidAccessToken), + credentials: HTTPAuthorizationCredentials = Depends(security), + service: AuthService = Depends(), +): + return RemoveNoneResponse(await service.get_me(user_info, credentials.credentials)) + + @router.get( path="/popup/status", response_model=Res_PopupStatus, @@ -92,17 +106,3 @@ async def hide_popup( service: AuthService = Depends(), ): return RemoveNoneResponse(await service.hide_popup(user_info, credentials.credentials, req.popup_type)) - - -@router.get( - path="/me", - response_model=Res_Me, - summary="내 정보 (보호된 엔드포인트)", - description="access 토큰 검증(validator) 후 su_id DB 존재/활성 + 저장 토큰 대조를 service 에서 확인해 반환한다.", -) -async def me( - user_info: UserInfo = Depends(IsValidAccessToken), - credentials: HTTPAuthorizationCredentials = Depends(security), - service: AuthService = Depends(), -): - return RemoveNoneResponse(await service.get_me(user_info, credentials.credentials)) diff --git a/backend/tests/test_auth.py b/backend/tests/test_auth.py index 696c465..916b3b3 100644 --- a/backend/tests/test_auth.py +++ b/backend/tests/test_auth.py @@ -371,3 +371,8 @@ async def test_popup_hide_invalid_type(client, account_seed): async def test_popup_status_without_token(client): r = await client.get("/v1/auth/popup/status") assert r.status_code in (401, 403) + + +async def test_popup_hide_without_token(client): + r = await client.post("/v1/auth/popup/hide", json={"popup_type": "service_info"}) + assert r.status_code in (401, 403) # HTTPBearer 가 자격증명 없음을 거부