[FEAT] 비공개방 비밀번호 입력 기반 입장 처리 및 직접 URL 접근 제어#109
Hidden character warning
Conversation
Walkthrough비공개방 입장용 비밀번호 검증과 세션 기반 인증 플래그(ROOM_AUTH_{roomId})를 추가하고, 클라이언트/JS·컨트롤러·DAO간 입장 흐름과 직접 URL 접근 제어를 구현했습니다. 리다이렉트 경로 일부가 Changes
Sequence Diagram(s)sequenceDiagram
participant Client
participant LobbyJS as Lobby (lobby.js)
participant EnterCtrl as EnterRoomController
participant RoomDAO
participant DB
participant Session
participant ViewCtrl as ViewRoomController
rect rgb(200,220,255)
note right of Client: 클라이언트 입장 시 (엔터 버튼)
Client->>LobbyJS: submit enter-room-form (roomId, isPublic)
alt isPublic == private
LobbyJS->>Client: prompt for password
Client->>LobbyJS: provide roomPwd
LobbyJS->>EnterCtrl: POST /room/enter (roomId, roomPwd)
else public
LobbyJS->>EnterCtrl: POST /room/enter (roomId)
end
end
rect rgb(220,240,220)
note right of EnterCtrl: 서버: 비공개 여부/비밀번호 검사
EnterCtrl->>RoomDAO: isPrivateRoom(roomId)
RoomDAO->>DB: SELECT ... room_pwd IS NOT NULL
DB-->>RoomDAO: result
RoomDAO-->>EnterCtrl: isPrivate
alt isPrivate
EnterCtrl->>RoomDAO: matchRoomPassword(roomId, roomPwd)
RoomDAO->>DB: SELECT ... room_pwd = ?
DB-->>RoomDAO: match?
RoomDAO-->>EnterCtrl: matched
alt matched
EnterCtrl->>Session: set ROOM_AUTH_{roomId} = true
EnterCtrl-->>Client: redirect /room?roomId=...
else not matched
EnterCtrl-->>Client: redirect /room/enter?error=wrong_password
end
else not private
EnterCtrl->>Session: set ROOM_AUTH_{roomId} = true
EnterCtrl-->>Client: redirect /room?roomId=...
end
end
rect rgb(255,240,200)
note right of Client: 직접 URL 접근 시
Client->>ViewCtrl: GET /room?roomId=...
ViewCtrl->>RoomDAO: isPrivateRoom(roomId)
RoomDAO->>DB: SELECT ...
DB-->>RoomDAO: result
RoomDAO-->>ViewCtrl: isPrivate
alt isPrivate and not Session[ROOM_AUTH_{roomId}]
ViewCtrl-->>Client: redirect /room/enter?roomId=...
else allowed
ViewCtrl-->>Client: forward room view
end
end
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Possibly related PRs
Suggested reviewers
개요 섹션의 내용은 변경사항에 맞게 위와 같이 업데이트되었습니다. Pre-merge checks and finishing touches❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing touches
🧪 Generate unit tests (beta)
Comment |
There was a problem hiding this comment.
Actionable comments posted: 5
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
src/main/java/room/controller/ExitRoomController.java (1)
25-35: roomId null 처리 검증 필요
roomId가 null인 경우session.removeAttribute("ROOM_AUTH_" + null)이 실행되어 의도하지 않은 세션 키를 제거할 수 있습니다.exitAndHandleHost가 실패하면 예외로 처리되지만, 방어적으로 roomId를 먼저 검증하는 것이 좋습니다.🔎 제안하는 수정
String roomId = request.getParameter("roomId"); HttpSession session = request.getSession(false); String userId = (session == null) ? null : (String)session.getAttribute("loginUserId"); + +if (roomId == null || roomId.isBlank()) { + response.sendRedirect(ctx + "/lobby?error=invalid_room"); + return; +} + if (userId == null || userId.isBlank()) {
🧹 Nitpick comments (1)
src/main/java/lobby/controller/CreateRoomController.java (1)
61-69: 방어적 프로그래밍: roomId null 체크 권장
roomResult.getId()가 null을 반환할 가능성은 낮지만, 세션 속성 키 생성 전에 null 체크를 추가하면 더 안전합니다.🔎 제안하는 방어 코드
String roomId = roomResult.getId(); + +if (roomId == null || roomId.isBlank()) { + throw new ServletException("방 ID 생성 실패"); +} session.setAttribute("hostUserId", hostUserId);
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (8)
src/main/java/lobby/controller/CreateRoomController.javasrc/main/java/room/controller/EnterRoomController.javasrc/main/java/room/controller/ExitRoomController.javasrc/main/java/room/controller/ViewRoomController.javasrc/main/java/room/dao/RoomDAO.javasrc/main/java/room/dao/RoomDAOImpl.javasrc/main/webapp/WEB-INF/views/room/create.jspsrc/main/webapp/static/lobby/lobby.js
🧰 Additional context used
🧬 Code graph analysis (5)
src/main/java/room/controller/ExitRoomController.java (3)
src/main/java/room/ws/RoomWebSocketService.java (2)
cleanup(105-113)onExit(80-102)src/main/java/room/service/RoomService.java (2)
RoomService(9-226)exitAndHandleHost(21-225)src/main/java/room/ws/RoomSessionRegistry.java (1)
leave(26-36)
src/main/java/room/dao/RoomDAO.java (3)
src/main/java/room/dao/RoomPlayerDAO.java (2)
RoomPlayerDAO(7-24)enterIfAbsent(11-11)src/main/java/game/single/dao/SinglePlayerDAO.java (1)
SinglePlayerDAO(3-13)src/main/java/game/multi/dao/MultiPlayerDAO.java (1)
MultiPlayerDAO(3-13)
src/main/java/lobby/controller/CreateRoomController.java (2)
src/main/webapp/static/room/room.js (6)
roomId(3-3)send(244-250)setStatus(138-141)pageEl(1-344)setStatus(237-237)location(240-242)src/main/java/room/ws/RoomWebSocketService.java (2)
onEnter(50-66)broadcastHostChanged(130-139)
src/main/java/room/controller/EnterRoomController.java (1)
src/main/java/room/dao/RoomDAOImpl.java (1)
RoomDAOImpl(15-252)
src/main/java/room/controller/ViewRoomController.java (3)
src/main/webapp/static/room/room.js (1)
roomId(3-3)src/main/java/room/controller/CreateRoomController.java (1)
WebServlet(15-61)src/main/java/lobby/controller/ViewRoomListController.java (1)
Override(22-45)
🔇 Additional comments (11)
src/main/java/lobby/controller/CreateRoomController.java (1)
68-73: 방 생성자에게 자동 인증 부여 로직 확인 완료방 생성 후 세션에
ROOM_AUTH_<roomId>플래그를 설정하여 방장이 비밀번호 입력 없이 입장할 수 있도록 처리한 로직이 정확합니다./room/enter로의 리다이렉트도 새로운 입장 플로우와 일치합니다.src/main/java/room/controller/ExitRoomController.java (1)
35-35: 세션 정리 로직 확인 완료방 퇴장 후
ROOM_AUTH_<roomId>세션 속성을 제거하여 인증 정보를 정리하는 로직이 올바르게 구현되었습니다.src/main/java/room/controller/ViewRoomController.java (1)
36-43: 비공개방 접근 제어 로직 검증 필요현재 구현은
ROOM_AUTH_<roomId>세션 플래그를 확인하여 비공개방 접근을 제어합니다. 그러나EnterRoomController와 달리 방장(host) 예외 처리가 없습니다.시나리오: 방장의 세션이 만료되거나 방장이 URL을 직접 입력하면, 자신이 만든 방임에도 불구하고
/room/enter로 리다이렉트됩니다.의도된 동작인지 확인이 필요합니다:
- 의도된 경우: 모든 사용자(방장 포함)가
/room/enter를 거쳐야 함 → 현재 코드 유지- 의도되지 않은 경우: 방장은 세션 플래그 없이도 접근 가능해야 함 →
EnterRoomController(line 66)와 같은 방장 확인 로직 추가 필요🔎 방장 예외 처리를 추가하는 경우의 수정안
+String userId = (String)session.getAttribute("loginUserId"); +String hostUserId = roomDAO.findHostUserIdByRoomId(roomId); +boolean isHost = userId != null && userId.equals(hostUserId); + boolean isPrivate = roomDAO.isPrivateRoom(roomId); Boolean isRoomAuthed = (Boolean)session.getAttribute("ROOM_AUTH_" + roomId); -if (isPrivate && (isRoomAuthed == null || !isRoomAuthed)) { +if (isPrivate && !isHost && (isRoomAuthed == null || !isRoomAuthed)) { response.sendRedirect("/room/enter?roomId=" + URLEncoder.encode(roomId, StandardCharsets.UTF_8) + "&playType=" + URLEncoder.encode(playType, StandardCharsets.UTF_8)); return; }src/main/webapp/WEB-INF/views/room/create.jsp (1)
190-194: 공개/비공개 값 변경 확인 완료
isPublic값을 "0"(공개), "1"(비공개)로 변경한 것이 서버 측 로직(RoomDAOImplline 111-115)과 일치합니다. UI 동작은 그대로 유지되며 의미적 일관성이 확보되었습니다.src/main/java/room/dao/RoomDAO.java (1)
32-52: 새로운 DAO 메서드 추가 확인 완료비공개방 비밀번호 검증(
matchRoomPassword)과 비공개방 여부 확인(isPrivateRoom) 메서드가 적절히 추가되었습니다. Javadoc 문서화도 명확합니다.src/main/webapp/static/lobby/lobby.js (2)
82-86: 공개/비공개 판별 로직 변경 확인 완료
isPublic값 해석을 "0"=공개, 그 외=비공개로 변경하여 서버 측 로직과 일치시켰습니다. 숨겨진 입력 필드를 통해 폼 제출 시 공개/비공개 정보가 올바르게 전달됩니다.Also applies to: 102-102
110-142: 비공개방 비밀번호 입력 플로우 구현 확인 완료비공개방 입장 시
prompt를 통해 비밀번호를 입력받고, 유효성을 검증한 후 폼에 숨겨진 필드로 추가하여 제출하는 로직이 올바르게 구현되었습니다.src/main/java/room/dao/RoomDAOImpl.java (2)
195-215: 비밀번호 검증 메서드 구현 확인 완료
matchRoomPassword메서드가 SQLCOUNT(*)를 사용하여 비공개방 여부(is_public='1')와 비밀번호 일치(room_pwd=?)를 동시에 확인합니다. 로직이 정확하며 리소스 관리도 try-with-resources로 안전하게 처리됩니다.
217-239: 비공개방 확인 메서드 구현 확인 완료
isPrivateRoom메서드가room_pwd IS NOT NULL을 통해 비공개방 여부를 확인합니다.COUNT(*)는 항상 결과를 반환하므로 line 236의return false는 방어 코드입니다. 현재 사용 사례에 적합한 구현입니다.src/main/java/room/controller/EnterRoomController.java (2)
27-37: GET/POST 요청 통합 처리 확인 완료
doGet과doPost를 공통handler메서드로 위임하여 코드 중복을 제거하고 일관된 처리를 보장합니다.
66-77: 비공개방 비밀번호 검증 및 방장 우회 로직 확인비공개방 입장 시 방장이 아닌 사용자에게만 비밀번호 검증을 요구하고, 검증 성공 시 세션에
ROOM_AUTH_<roomId>플래그를 저장하는 로직이 올바르게 구현되었습니다. (단, line 59의 NPE 이슈 수정이 선행되어야 합니다)
There was a problem hiding this comment.
Actionable comments posted: 2
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (4)
src/main/java/room/controller/EnterRoomController.javasrc/main/java/room/controller/ViewRoomController.javasrc/main/java/room/dao/RoomDAO.javasrc/main/webapp/static/lobby/lobby.js
🚧 Files skipped from review as they are similar to previous changes (1)
- src/main/webapp/static/lobby/lobby.js
🧰 Additional context used
🧬 Code graph analysis (3)
src/main/java/room/controller/ViewRoomController.java (1)
src/main/webapp/static/room/room.js (1)
roomId(3-3)
src/main/java/room/dao/RoomDAO.java (1)
src/main/webapp/static/room/room.js (1)
roomId(3-3)
src/main/java/room/controller/EnterRoomController.java (1)
src/main/java/room/dao/RoomDAOImpl.java (1)
RoomDAOImpl(15-252)
🔇 Additional comments (12)
src/main/java/room/dao/RoomDAO.java (2)
32-45: 메서드 시그니처와 문서화가 명확합니다.비공개방 비밀번호 검증 로직의 계약이 Javadoc에 잘 정의되어 있습니다. 공개방/비공개방 처리 규칙과 반환값이 명확하게 문서화되었습니다.
47-52: 메서드 문서화가 적절합니다.비공개방 여부 조회 메서드의 목적과 파라미터가 명확하게 정의되어 있습니다.
src/main/java/room/controller/ViewRoomController.java (4)
4-5: 컨텍스트 경로 처리가 올바르게 적용되었습니다.
URLEncoder및StandardCharsetsimport와request.getContextPath()사용으로 이전 리뷰에서 지적된 하드코딩된 경로 문제가 해결되었습니다.Also applies to: 26-26
33-36: 파라미터 검증 및 리다이렉트가 적절합니다.필수 파라미터와 세션에 대한 조기 검증과 명시적인 return 처리가 올바르게 구현되었습니다.
38-45: 비공개방 접근 제어 로직이 올바르게 구현되었습니다.세션 기반 인증 플래그(
ROOM_AUTH_<roomId>)를 확인하여 비인증 사용자를/room/enter로 리다이렉트하는 로직이 정확합니다. URL 파라미터 인코딩과 null 처리가 적절합니다.다만,
EnterRoomController에서 방장(host)이 비공개방 입장 시ROOM_AUTH플래그를 설정하는지 확인이 필요합니다. 방장이 비밀번호 없이 입장 가능하다는 요구사항이 있으므로, 방장도 이 플래그를 받아야 이후/room접근이 정상 동작합니다.
54-54: 방장 조회 실패 시 에러 처리가 적절합니다.컨텍스트 경로를 포함한 리다이렉트와 명확한 에러 파라미터가 올바르게 구현되었습니다.
src/main/java/room/controller/EnterRoomController.java (6)
15-16: 핸들러 통합과 RoomDAO 추가가 적절합니다.GET과 POST 요청을 단일
handler메서드로 통합하여 코드 중복을 제거했으며,RoomDAO추가로 비공개방 검증 기능을 지원합니다.Also applies to: 28-37, 39-40
45-52: 파라미터 검증 순서가 개선되었습니다.이전 리뷰에서 지적된 문제(DB 호출 전 파라미터 검증 누락)가 해결되었습니다. 이제 null/blank 체크(49-52행)가 DB 호출(54-55행)보다 먼저 수행되어 잘못된 입력으로 인한 DB 에러를 방지합니다.
54-55: DB 조회 배치가 적절합니다.파라미터 검증 후 DB를 조회하는 순서가 올바르게 구현되었습니다.
57-63: userId null 체크가 수정되었습니다.이전 리뷰에서 지적된 NPE 위험(null 체크 전
userId.equals()호출)이 해결되었습니다. 이제 userId null/blank 검증(60-63행)이equals호출(65행)보다 먼저 수행됩니다.
68-76: 비밀번호 검증 로직이 정확하게 구현되었습니다.비공개방에 대한 비밀번호 입력 확인(68-71행)과 검증(73-76행)이 올바르게 분리되어 있으며, 각 실패 케이스에 적절한 에러 메시지(
need_password,wrong_password)를 제공합니다.
80-86: 방 입장 및 리다이렉트 처리가 적절합니다.
enterIfAbsent호출, 로비 브로드캐스트, 그리고 URL 인코딩된 파라미터를 사용한/room으로의 리다이렉트가 올바르게 구현되었습니다.
📌 작업 내용
ROOM_AUTH_<roomId>) 저장/room) 접근 시 세션 인증 정보가 없으면/room/enter로 리다이렉트되도록 제어🔗 관련 이슈
👀 리뷰 시 참고사항
💭 느낀 점
💻 스크린샷 (선택)
Summary by CodeRabbit
새로운 기능
버그 수정 / 동작 변경
기타
✏️ Tip: You can customize this high-level summary in your review settings.