회원 목록은 로그인 사용자만, 개인정보 수정은 “본인만” 가능하게 만들기
웹 애플리케이션에서 기능 구현만큼 중요한 것이 접근 제어다.
화면에서 버튼을 숨겼다고 보안이 되는 것이 아니다.
서버에서 직접 요청을 차단하지 않으면 언제든 우회가 가능하다.
이번 단계에서는 다음 두 가지 요구사항을 서버 레벨에서 정확히 구현한다.
- 회원 목록(/user/list)은 로그인한 사용자만 접근 가능
- 개인정보 수정(/user/updateForm, /user/update)은 본인만 가능
핵심 도구는 세션(Session) 이다.
회원 목록은 로그인 사용자만 접근 가능하게
왜 서블릿에서 막아야 하는가?
`/user/list`는 단순한 HTML 페이지가 아니다.
- 서블릿이 DB에서 사용자 목록을 조회하고
- request에 데이터를 담아서
- JSP로 forward하는 데이터 제공용 엔드포인트다
즉,
로그인하지 않은 사용자가 이 URL에 접근하면 안 된다.
메뉴에서 링크를 숨기는 것만으로는 부족하다.
URL을 직접 치거나, 즐겨찾기, 개발자 도구로 요청하면 그대로 접근 가능하기 때문이다.
ListUserServlet 수정 핵심 코드
HttpSession session = req.getSession(false);
User loginUser = (session == null) ? null : (User) session.getAttribute("user");
if (loginUser == null) {
resp.sendRedirect("/user/login.jsp");
return;
}
코드 흐름 설명
- req.getSession(false)
- 세션이 없으면 새로 만들지 않고 null 반환
- 접근 검사에서는 이게 맞다
- 세션이 있으면 session.getAttribute("user")로 로그인 사용자 조회
- 로그인 사용자가 없으면
- `/user/login.jsp`로 `redirect`
- 이후 로직 실행을 막기 위해 `return`
이 검사 이후에만 회원 목록 조회 + JSP forward가 실행된다.
요구사항 대응
- 회원 목록 조회는 로그인 사용자만 가능
- 서버에서 직접 차단 → 우회 불가
개인정보 수정은 “본인만” 가능하게
이 단계가 훨씬 중요하다.
왜 더 엄격해야 하는가?
개인정보 수정은 다음 두 가지 요청으로 나뉜다.
- GET `/user/updateForm?userId=xxx`
→ 수정 폼 보여주기 - POST `/user/update`
→ 실제 수정 처리
“GET만 막으면 되지 않나?”
❌ 아니다.
POST 요청은 브라우저 없이도 직접 보낼 수 있다.
즉, GET만 막으면 폼은 못 보지만 수정은 가능해진다.
그래서 GET과 POST 둘 다 검사해야 보안이 완성된다.
공통 권한 검사 로직 (개념)
HttpSession session = req.getSession(false);
User loginUser = (session == null) ? null : (User) session.getAttribute("user");
if (loginUser == null) {
resp.sendRedirect("/user/login.jsp");
return;
}
String userId = req.getParameter("userId");
if (!loginUser.getUserId().equals(userId)) {
resp.sendRedirect("/user/list");
return;
}
검사 조건 정리
- 로그인 여부 검사
- 세션에 user가 없으면 로그인 페이지로 이동
- 본인 여부 검사
- 요청 파라미터의 userId
- 세션에 저장된 loginUser.userId
- 두 값이 일치할 때만 허용
이 조건을 통과하지 못하면 즉시 redirect + return 한다.
왜 GET / POST 둘 다 필요한가?
- GET만 검사하면
→ 폼은 못 보지만, POST로 직접 수정 가능 - POST만 검사하면
→ 다른 사람 정보가 폼에 노출될 수 있음
그래서 두 단계 모두 막아야 한다.
요구사항 대응
- 개인정보 수정은 본인만 가능
- URL 직접 접근, POST 직접 요청 모두 차단
수정 폼에 사용자 정보 전달하기
권한 검사를 통과했다면, 이제 수정 폼에 기존 사용자 정보를 보여줘야 한다.
UpdateUserServlet 코드
User user = DataBase.findByUser(userId);
req.setAttribute("user", user);
RequestDispatcher rd = req.getRequestDispatcher("/user/updateForm.jsp");
rd.forward(req, resp);
- DB에서 사용자 조회
- request에 "user"라는 이름으로 저장
- JSP로 forward
이렇게 하면 `updateForm.jsp`에서 다음과 같이 사용할 수 있다.
${user.userId}
${user.name}
${user.email}
즉,
- 서블릿은 데이터 준비
- JSP는 화면 출력
역할이 명확히 분리된다.
전체 흐름 요약
회원 목록
- /user/list
- 로그인 검사 추가
- 로그인 사용자만 접근 가능
개인정보 수정
- /user/updateForm, /user/update
- 로그인 여부 + 본인 여부 검사
- GET/POST 모두 차단 로직 적용
결과
- 다른 사용자 ID로 접근 불가
- 직접 POST 요청으로도 수정 불가
- 서버 레벨에서 완전 차단
정리
- 화면에서 막는 건 보안이 아니다
- 서버에서 검사하지 않으면 항상 뚫린다
- 로그인 여부 → 세션
- 본인 여부 → 세션 userId vs 요청 userId 비교
- GET / POST 둘 다 검사해야 진짜 보안이다
출처 : 《자바 웹 프로그래밍 Next Step》, 박재성, 로드북
'Book > 자바 웹 프로그래밍 Next Step' 카테고리의 다른 글
| 6장_ : 쿠키와 UUID로 세션 아이디 직접 생성 (0) | 2026.02.08 |
|---|---|
| 6장_ : 쿠키와 세션 (0) | 2026.02.07 |
| 6장_ 요구사항3 : 세션 기반 로그인/로그아웃 상태 만들기 (0) | 2026.02.07 |
| 6장_ 요구사항1: 개인정보 수정 (0) | 2026.02.06 |
| 6장_ : ListUser 화면 구현 (0) | 2026.02.06 |
