diff --git "a/static/06_\353\215\260\354\235\264\355\204\260\353\252\250\353\215\270_\353\260\217_\353\254\264\352\262\260\354\204\261.md" "b/static/06_\353\215\260\354\235\264\355\204\260\353\252\250\353\215\270_\353\260\217_\353\254\264\352\262\260\354\204\261.md" index fd36606..2d97031 100644 --- "a/static/06_\353\215\260\354\235\264\355\204\260\353\252\250\353\215\270_\353\260\217_\353\254\264\352\262\260\354\204\261.md" +++ "b/static/06_\353\215\260\354\235\264\355\204\260\353\252\250\353\215\270_\353\260\217_\353\254\264\352\262\260\354\204\261.md" @@ -400,7 +400,7 @@ ALTER TABLE place ADD CONSTRAINT ck_place_lng CHECK (lng BETWEEN -180 AND 180); ### 5.3 식별자 은닉 -- `member.id`는 **공개 응답(타인 조회)에 포함하지 않습니다.** 순차 값이므로 노출 시 사용자 열거가 가능해지고, 가입 순번이 신원 추론 단서가 됩니다. 예외적으로 로그인·가입 확정 응답에만 본인의 id(`memberId`)를 반환합니다. +- `member.id`는 **공개 응답(타인 조회)에 포함하지 않습니다.** 익명 서비스에서 클라이언트에게 **여러 응답을 가로질러 조인할 전역 키**를 주지 않기 위한 조항입니다. 진입점이 `collectionId`이면 작성자별 묶어보기는 서버가 내주는 범위(Shelf)로 한정되지만, 공개 응답에 `memberId`가 실리면 클라이언트가 모든 응답을 자기 마음대로 결합할 수 있습니다. 본인의 id도 응답에 담지 않습니다 — 쿠키 인증이므로 클라이언트가 자신의 `memberId`를 알 필요가 없습니다([08 §1.1](08_API_명세.md)). - 별도 공개 식별자(`public_id`)는 두지 않습니다. 대신 **Collection id를 진입점**으로 사용합니다. ```text @@ -409,8 +409,12 @@ GET /feed/collections/{collectionId}/shelf -- 같은 선반의 다른 공개 Co GET /follows -- 서버가 follow 테이블로 조회 ``` -- Collection id는 발행 시 공개 대상이므로 노출되어도 정책 위반이 아닙니다. 사용자 열거와는 성격이 다릅니다. -- 향후 Shelf 전용 URL(새로고침·공유 가능한 페이지)이 필요해지면 그때 `member.public_id UUID`를 추가합니다. 기존 행은 일괄 UPDATE로 채울 수 있습니다. +- Collection id는 발행 시 공개 대상이므로 노출되어도 정책 위반이 아닙니다. Collection 하나를 가리키는 값이어서 작성자를 가로지르는 결합 키가 되지 않습니다. +- 향후 Shelf 전용 URL(새로고침·공유 가능한 페이지)이 필요해지면 그때 `member.public_id UUID`를 추가합니다. 기존 행은 일괄 UPDATE로 채울 수 있습니다. **순차 `member.id`를 그대로 공개하는 방식은 채택하지 않습니다** — 얻는 것은 UUID 안과 같은데, 공개 응답에 필드가 한 번 들어가면 Front가 그것에 묶여 제거가 계약 파괴가 되므로 되돌릴 수 없는 쪽을 고르지 않습니다. + +**막는 층은 공개 DTO 하나입니다.** `member.id`에는 §5.2의 쿼리 분리가 적용되지 않습니다 — 조회 결과에 `member_id`가 실려 오더라도 공개 DTO에 그 필드가 없으면 충족됩니다. §5.2의 쿼리 분리는 `context.body`를 대상으로 하는 별개 조항이며, 두 조항을 섞어 공개 조회 쿼리를 따로 두는 근거로 쓰지 않습니다. + +**실제 방어선은 식별자 은닉이 아니라 접근 통제입니다.** id를 아는 것 자체는 그 id로 남의 데이터에 접근할 수 있을 때만 위험합니다. 개인 API는 사용자 ID를 Query나 Body로 받지 않고 서버가 쿠키로 식별하며([08 §1.1](08_API_명세.md)), id를 받는 모든 엔드포인트는 소유권을 확인하고 실패 시 403이 아니라 404로 존재를 은닉합니다(§5.5). 이 절을 "id를 숨겼으니 안전하다"로 읽으면 그 방어선을 빠뜨리게 됩니다. ### 5.4 공개 Keyword의 전제