본문 바로가기

Spring/Benepicture 홈페이지

[베네픽처 홈페이지] 로그인 기능 구현 (세션, 서블릿 필터)

이전에 구현한 로그인은 단순히 DB에서 아이디와 비밀번호를 찾고 일치하면 해당 페이지를 보여주는 방식이였습니다.

이번에는 쿠키, 세션 방식을 활용하고 filter를 적용하여 로그인이 필요한 페이지를 구분하는 기능까지 구현하였습니다.

 

개념적으로 중요한 기술들이지만 우선.. 적용을 위주로 간략하고 짧게 설명하겠습니다.

 

쿠키

쿠키는 클라이언트(브라우저)에 저장되는 키와 값으로 이루어진 데이터 파일입니다.

HTTP는 무상태 프로토콜입니다.

즉, 클라이언트와 서버가 요청과 응답을 주고 받은 이후 클라이언트가 다시 요청을 한다고해서 이전 요청을 기억하지 않습니다.

하지만 로그인 등 이전에 대한 기억이 필요한 경우 쿠키를 클라이언트에 저장 후 다음 응답에 쿠키를 같이 전달하여 이전의 기억을 유지할 수 있습니다.

 

쿠키의 주 사용처 : 사용자 로그인 세션 관리, 광고 정보 트래킹 등

 

쿠키는 최소한의 정보만 사용해야 합니다.

크키는 항상 서버로 전송되며 쿠키의 용량이 커지면 네트워크 트래픽을 추가로 발생시킵니다.

또한, 보안에 민감한 데이터는 저장하면 안됩니다. 클라이언트에 저장되므로 언제든 위,변조가 가능합니다.

 

세션

세션은 쿠키를 기반으로 사용자 정보 파일을 브라우저에 저장하는 것이 아닌 서버 측에서 관리합니다.

이전과 같이 쿠키를 주고 받지만 클라이언트에게 주는 쿠키에는 추정 불가능한 세션 ID 값을 전달하고

서버에서는 세션 저장소를 만들어 세션 ID값과 중요 정보를 매칭합니다.

 

세션을 사용해서 서버에서 중요한 정보를 관리하여 클라이언트의 쿠키값이 위,변조 되더라도 실제 중요 정보는 훼손되지 않습니다.

 

세션의 주 사용처 : 로그인 같이 보안상 중요한 작업

 

세션은 각 클라이언트에게 세션 ID를 전달하여 쿠키 대비 보안이 뛰어나지만

사용자가 많아질수록 세션 저장소(서버DB)의 메모리를 많이 차지하게 됩니다.

 

쿠키와 세션의 차이

둘 다 쿠키를 기반으로 정보가 왔다갔다 하지만 가장 큰 차이점은 사용자의 정보가 저장되는 위치입니다. 쿠키는 클라이언트 세션은 서버에 정보를 저장합니다. 

보안 면에서는 세션이 뛰어나지만 속도는 쿠키가 더 빠릅니다. (세션의 경우 서버에서 변환 처리가 필요합니다.)

 

최근에는 이러한 방식을 보완한 토큰 기반의 인증방식을 많이 사용합니다.

(토큰은 나중에 정리하겠습니다.)

 

 

필터

로그인 구현을 하다보면 관리자 페이지, 공지사항 추가, 광고 보기 등 로그인이 유지되어야 하는 페이지들이 다양하게 존재합니다.

하지만 이러한 페이지들을 전부 다 반복되는 세션 체크 코드를 사용하다보면.. 이러한 공통 관심 사항을 묶을 수 없을까라는 고민을 하게 됩니다.

 

이러한 공통 관심사는 스프링의 AOP로도 해결할 수 있지만 웹과 관련된 공통 관심사는 서블릿 필터 또는 스프링 인터셉터를 사용하는 것이 좋습니다.

(웹과 관련된 공통 관심사를 처리할 때는 HTTP헤더나 URL 정보가 필요한데 이러한 정보들을 서블릿 필터나 스프링 인터셉터는 제공을 해줍니다.)

 

필터의 흐름을 보면

 

더보기

HTTP 요청 >> WAS >> 필터 >> 서블릿 >> 컨트롤러

 

이러한 방식으로 서블릿 앞단에서 호출이 됩니다.

 

이 기능을 활용한다면 로그인이 필요한 페이지들의 경우 필터단에서 서블릿 호출을 막을 수 있습니다.

 

필터는 체인 형태로 

 

더보기

HTTP 요청 >> WAS >> 필터1 >>  필터2 >> 필터3 >>  서블릿 >> 컨트롤러

 

이러한 형태로도 사용 가능합니다.

 

- 필터 인터페이스

필터 인터페이스를 구현하고 등록하면 서블릿 컨테이너가 필터를 싱글톤 객체로 생성하고 관리합니다.

필터 인터페이스는 3가지 메소드를 갖고 있습니다.

 

더보기

init() : 필터 초기화 메서드로 서블릿 컨테이너가 생성될 떄 호출됩니다.

doFilter() : 요청이 들어올 때 마다 메서드가 호출됩니다. (필터 로직이 들어갑니다.)

destroy() : 필터 종료 메서드로 서블릿 컨테이너가 종료될 때 호출됩니다.

 

 

 

적용

기존에 로그인과 비슷하나 주요하게 볼 부분은 로그인에 성공 후

스프링에서 제공하는 session을 활용하여 SessionConst.LOGIN_USER라는 상수와 값을 넘겨줍니다.

 

로그아웃시에는 session.invalidate();를 적용해주면 세션을 없애고 세션에 포함된 값들을 모두 제거합니다.

 

 

 

필터 적용을 설명드리겠습니다.

 

@Configuration 애노테이션을 사용하여 컨테이너에 필터와 관련된 빈을 등록시켜줍니다.

 

위에서 설명한 Filter 인터페이스를 상속받아서 doFIlter를 구현하였습니다.

(init과 destroy는 필수 구현 메소드가 아니여서 생략 가능합니다.)

whitelist의 등록된 URL들을 제외하고는 이전에 로그인 시 생성한  session값이 유효한지를 확인합니다.

session값이 유효하지 않다면 404에러를 보여주게 됩니다.