로그인 요구사항
홈 화면 - 로그인 전
>> 회원 가입
>> 로그인
홈 화면 - 로그인 후
>> 본인 이름(누구님 환영합니다.)
>> 상품 관리
>> 로그 아웃
보안 요구사항
>> 로그인 사용자만 상품에 접근, 관리 가능
>> 로그인 하지 않은 사용자가 상품 관리에 접근하면 로그인 화면으로 이동
회원 가입, 상품 관리
Package 구조
도메인이 가장 중요!
>> 도메인 = 화면, UI, 기술 인프라 등의 영역을 제외한 시스템이 구현해야 하는 핵심 비즈니스 업무 영역
향후 web을 다른 기술로 바꿔도 도메인은 그대로 유지할 수 있어야 함
>> web은 domain을 의존하지만 domain은 web을 의존하지 않게 설계
로그인 처리하기 - 쿠키 사용
쿠키
서버에서 로그인에 성공하면 HTTP 응답에 쿠키를 담아 브라우저에 전달
>> 브라우저는 앞으로 해당 쿠키를 지속해서 보냄
세션 쿠키 : 만료 날짜를 생략하면 브라우저 종료시까지 유지
쿠키 생성 로직
로그인에 성공하면 쿠키를 생성하고 HttpServletResponse에 담음
>> 쿠키 이름은 memberId, 값은 회원이 id를 담음
로그인 처리
@CookieValue를 사용해서 편리하게 쿠키 조회
로그인 하지 않은 사용자도 홈에 접근할 수 있기 때문에
>> required = false 사용
로그인 쿠키(memberId)가 없는 사용자는 기존 home으로 보냄
>> 로그인 쿠키가 있어도 회원이 없으면 home으로 보냄
로그인 쿠키(memberId)가 있는 사용자는 전용 홈 화면인 loginHome으로 보냄
>> 홈 화면에 회원 관련 정보도 출력해야 하기 때문에 member 데이터도 모델에 담아 전달
로그아웃 기능
서버에서 해당 쿠키의 종료 날짜를 0으로 지정
쿠키와 보안 문제
쿠키 값은 임의로 변경 가능
>> 클라이언트가 쿠키를 강제로 변경하면 다른 사용자가 됨
>> 실제 웹 브라우저 개발자모드 => Application => Cookie 변경 으로 확인
쿠키에 보관된 정보는 훔치기 가능
>> 쿠키의 정보가 내 로컬 PC에서 털릴 수도, 네트워크 전송 구간에서 털릴 수도 있음
해커가 쿠키를 한번 훔쳐가면 평생 사용 가능
>> 악의적인 요청 계속 시도 가능
대안
>> 쿠키에 중요 값을 노출 x, 사용자 별로 예측 불가능한 임의 토큰 노출
>> 서버에서 토큰과 사용자 id를 매핑해서 인식, 서버에서 토큰 관리
>> 토큰은 해커가 임의 값을 넣어도 찾을 수 없게 예상 불가능 해야 함
>> 토큰을 털어가도 시간이 지나면 사용하지 못하게 서버에서 토큰의 만료시간을 짧게 유지
>> 서버에서 해킹이 의심되면 토큰 강제 제거
로그인 처리하기 - 세션 동작
서버에 중요한 정보를 보관하고 연결을 유지하는 방법
동작 방식
사용자가 loginId, password 정보를 전달하면 서버에서 해당 사용자가 맞는지 확인
세션 ID 생성
>> UUID는 추정 불가
생성된 세션 ID와 세션에 보관할 값(memberA)를 서버의 세션 저장소에 보관
클라이언트와 서버는 결국 쿠키로 연결돼야 함
>> mySessionId라는 이름으로 세션 ID만 쿠키에 담아 전달
>> 클라이언트는 쿠키 저장소에 mySessionId 쿠키 보관
회원과 관련된 정보는 전혀 클라이언트에게 전달 x
클라이언트는 요청시 항상 mySessionId 쿠키 전달
>> 서버에서는 클라이언트가 전달한 mySessionId 쿠키 정보로 세션 저장소 조회, 로그인시 보관한 세션 정보 사용
세션 만들고 적용하기
세션 생성
>> sessionId 생성(임의의 추정 불가능한 랜덤 값)
>> 세션 저장소에 sessionId와 보관할 값 저장
>> sessionId로 응답 쿠키 생성해서 클라이언트에 전달
세션 조회
>> 클라이언트가 요청한 sessionId 쿠키의 값으로 세션 저장소에 보관한 값 조회
세션 만료
>> 클라이언트가 요청한 sessionId 쿠키의 값으로 세션 저장소에 보관한 sessionId와 값 제거
서블릿 HTTP 세션
HttpSession
서블릿을 통해 HttpSession을 생성하면
>> 쿠키 이름이 JSESSIONID이고 값은 추정 불가능한 랜덤 값인 쿠키 생성
>> Cookie: JSESSIONID=5B78E23B513F50164D6FDD8C97B0AD05
세션 생성과 조회
request.getSession(true)
>> 세션이 있으면 기존 세션 반환
>> 세션이 없으면 새로운 세션 생성 반환
request.getSession(false)
>> 세션이 있으면 기존 세션 반환
>> 세션이 없으면 새로운 세션 생성 x, null 반환
세션에 로그인 회원 정보 보관
session.setAttribute(SessionConst.LOGIN_MEMBER, loginMember);
>> 세션에 데이터를 보관 방법은 request.setAttribute(...)와 비슷, 하나의 세션에 여러 값 저장 가능
session.invalidate()
>> 세션 제거
@SessionAttribute
세션을 찾고, 세션에 들어있는 데이터를 찾는 번거로운 과정을 스프링이 편리하게 처리
>> 이 기능은 세션을 생성 x
TrackingModes
로그인을 처음 시도하면 URL이 jsessionid를 포함하고 있음
>> 웹 브라우저가 쿠키를 지원하지 않을 때 쿠키 대신 URL을 통해 세션을 유지하는 방법
>> 타임리프 같은 템플릿이 엔진을 통해 링크를 걸면 jsessionid를 URL에 자동 포함
>> 서버 입장에서는 웹 브라우저가 쿠키를 지원하는지를 최초에는 판단을 못해서 쿠키 값도 전달하고 URL에 jsessionid도 전달
세션 타임아웃 설정
세션은 로그아웃을 호출해서 session.invalidate()가 호출 되어야 삭제
>> 대부분은 웹 브라우저를 그냥 종료
>> HTTP가 비 연결성이어서 서버 입장에서는 사용자가 웹 브라우저를 종료한 지를 인식 불가
>> 서버에서 세션 데이터를 언제 삭제해야 하는 지 판단 어려움
남아있는 세션 무한정 보관
>> 쿠키(JSESSIONID)를 탈취 당했을 경우 오랜 시간이 지나도 악의적인 요청 가능
>> 세션은 메모리에 생성됨, 메모리 용량 문제
세션의 종료 시점
세션 생성 시점이 아닌 사용자가 서버에 최근에 요청한 시간을 기준으로 30분 정도 유지
>> HttpSession이 이 방식 사용
출처 : 김영한, 스프링 MVC 2편 - 백엔드 웹 개발 활용 기술
'Spring' 카테고리의 다른 글
MVC / 예외 처리와 오류 페이지 (0) | 2025.04.14 |
---|---|
MVC / 로그인 처리 - 필터, 인터셉터 (0) | 2025.04.13 |
MVC / Bean Validation (0) | 2025.04.11 |
MVC / Validation (0) | 2025.04.10 |
MVC / 메시지, 국제화 (0) | 2025.04.09 |