쿠키와 세션을 이용한 자동 로그인 방식에 대해서 정리해 보겠습니다.


[    1. 쿠키와 세션이란?    ]


: 쿠키와 세션은 매우 유사하면서도 다른 특징을 지니고 있는데요.

- 공통점 : 사용자의 정보(데이터)를 저장할 때 이용된다.

- 차이점 : 

- 쿠키 : 1) 사용자의 로컬에 저장되었다가 브라우저가 요청시 왔다갔다하게 됨(보안에 취약)

     2) 세션과 달리 여러 서버로 전송이 가능함

     3) 세션이 브라우저 단위로 생성되어 브라우저 종료시 사라지는데 반해, 쿠키는 유효시간 설정을 할 수 있음. ex) 7일

- 세션 : 1) 서버에 데이터를 저장하여 쿠키에 비해 보안에 안전함

     2) 브라우저 단위로 생성됨 => 익스플로러를 켜고 크롬을 켜고 하면 각각 2개의 세션이 생성되는 것


[    2. why 쿠키와 세션을 이용한 로그인 처리를 하게 될까?    ]


: 세션은 위에서 설명한대로 기본 단위가 "웹 브라우저"입니다. 따라서, 웹 브라우저 종료시 소멸하게 되죠...

  그에 반해 쿠키는 사용자 PC에 저장되기 때문에 서버 요청시 전달되는 동안 네트워크 상에서 보안상 취약할 수는 있지만 유효시간을

  길게 설정할 수 있어 브라우저가 종료되는 것과 별개로 7일 30일 등 기간을 길게 설정할 수 있습니다.

  하지만, 

  그렇다고 쿠키에 로그인할 사용자의 정보를 담고 있는다면 정말 정말 너무 너무 보안상 취약할 것을 알 수 있겠죠?

  따라서, 자동 로그인을 구현할 때에는 "< 세션과 쿠키를 동시에 사용하는 것 >"이 바람직하다고 생각합니다.


[    3. 세션과 쿠키를 이용한 자동 로그인 구현에 대한 개요    ]


: 사용자가 로그인 폼에서 로그인을 할 당시, 자동로그인을 설정하겠다는 CheckBox를 클릭할 경우 사용자의 정보를 저장시키고 유효

기간을 설정한다는 것 까지는 알겠는데 그럼 도대체 어떤 사용자의 정보를 저장시켜 놓아야할까요?


먼저, 사용자가 로그인에 성공한 경우! -> 세션에 사용자 객체(UserVO)를 저장시켰었는데 앞에서 이 객체를 쿠키에 저장시킨다면, 굉장히 보안상 취약합니다. 비밀번호, 아이디 그 외 정보까지 UserVO에 들어 있었죠...

따라서, 로그인에 성공했을 때 사용자 DB 테이블에 sessionId와 유효시간 속성에 값을 지정하는 겁니다. 그리고 쿠키에는 세션Id를

넣어 놓는거죠... 그리고 "인터셉터"에서 해당 쿠키값이 존재하면 사용자 DB 테이블 내에서 유효시간 > now() 즉, 유효시간이 아직 

남아 있으면서 해당 세션 Id를 가지고 있는 사용자 정보를 검색해 해당 사용자 객체를 반환하는 겁니다.


당연히, 쿠키가 유효시간이 다되면 해당 자동완성 기능은 동작하지 않게 되고 다시 쿠키를 사용하겠다는 선택을 했을 때 동작하게 되겠죠

그럼, 다음으로 코드상에서 직접 한번 알아 봅시다.


[    4. 자동 로그인 실재로 구현해보기    ]


이번 장의 예제는 앞 게시글을 다 수행했다는 가정하에서 진행됩니다.


1) 먼저, UserController에서 로그인에 성공했으면서 사용자가 쿠키 사용 여부를 체크한 경우 -> 쿠키를 생성하고 세팅합시다.

코드를 살펴보면, service 객체의 login메서드를 통해 UserVO 객체를 반환하고 null이 아닌 경우 로그인에 성공했었죠?

이렇게 로그인에 성공되었으면서, 로그인 폼에서 checkBox를 선택한 경우(쿠키 사용하겠다는 체크박스) submit을 했을 때

UserVO 클래스 내의 useCookie 변수에 true/false로 값이 저장되어 들어 왔을 테니까

로그인에 성공했으면서 + 쿠키사용을 체크한 경우에 세션을 추가하도록 하는 부분이 앞에 코드에서 추가된 겁니다.

이때, 사용자 PC에서 쿠키를 보내는 경로가 "/" 로 설정함으로써 contextPath 이하의 모든 요청에 대해서 쿠키를 전송할 수 있

도록 설정한다는 것이고, 유효시간은 (초)단위 임으로 60 * 60 * 24 * 7로 세팅해주면, 로그인 후 해당 쿠키는 7일동안 유지될 수

있게 됩니다.(브라우저의 종료와 관계없이)

이때, 가장 중요하게 볼 부분이 쿠키에 UserVO 객체를 저장하는 것이 아니고!!!!(사실 쿠키는 문자열만 저장되기 때문에 가능하지도 않습니다.)

현재 브라우저의 세션 id를 저장해 놓는 겁니다.


그럼... 쿠키에 의해 자동로그인 기간은 제어가 될 것이고... 사용자는 해당 세션 id에 대한 정보를 가지고 있어야 겠죠??

따라서, 다음으로는 DB의 userTable에 세션Id와 유효시간 정보를 담을 수 있는 컬럼을 추가하도록 합시다.


2) DB userTable에 세션Id와 유효시간을 설정할 수 있는 컬럼을 만들기


3) userMapper.xml에 작업을 합시다.

1. 로그인 성공시 sessionId와 유효시간을 저장하는 부분 작성

2. 사용자가 이전에 로그인에 성공했었는지 확인하는 부분


4) userDAO 인터페이스와 userDAOImpl 클래스를 수정합시다.


5) UserService 인터페이스와 UserServiceImpl 클래스 수정하기


6) UserController에서 로그인 성공하고 쿠키사용 체크한 경우에 사용자 테이블에 세션id와 유효시간 처리해주기

아까 쿠키를 생성해서 세션id 저장한 부분 바로 아래에다가 사용자 테이블에도 세션 id와 유효시간을 저장해 놓아야함!


이후, AuthenticationInterceptor의 preHandle() 부분에서 

세션에 UserVO 객체가 null이 아닌 경우는 로그인 되어 있는 부분이니까 그대로 처리되도록 놔두고, 세션의 UserVO 객체가

null이지만, 쿠키가 null이 아닌 경우 쿠키에서 sessionId를 꺼내와서 사용자 객체를 반환받도록 작업할 것이다.


7) AuthenticationInterceptor에서 자동 로그인의 핵심 부분을 처리하자.

AuthenticationInterceptor에서도 DB에 접근해서 처리를 해야함으로 UserService를 필드변수에 선언해주고 자동 주입을 위해

@Inject해주었다.

또한 preHandle() 메서드에서 로그인 세션이 없으면서 WebUtils를 이용해 쿠키를 가져온 뒤 

로그인 세션이 없지만, loginCookie가 존재하는 경우 웹브라우저를 새로 켜고 로그인을 하지는 않았지만 이전에 로그인 하면서

쿠키 체크를 해논 유효기간이 남아 있는 경우임으로 service.checkUserWithSessionKey() 메서드를 통해 DB에서 유효기간이 남아있고

해당 세션id를 가지고 있는 사용자 정보를 받아온다.

그리고 마지막으로 해당 사용자 정보로 세션의 login을 세팅해주면 자동로그인에 필요한 모든 작업이 완료되었다.


8) 로그아웃 처리(UserController에서...)

로그아웃 처리를 깜빡하고 마지막이랬다.. 하하하....


9) /views/board/listPge.jsp 에서 로그아웃 버튼 하나 넣기

<a href="/logout">[로그아웃]</a> 하나 추가하자 로그아웃 버튼!


10) 결과 확인하기


1) 로그인 하면서 로그인 상태를 기억하시겠습니까를 클릭하고 로그인 하는 모습

2) 로그인 한 직후 모습


3) 로그인 했음으로 글 작성 바로 잘 된다.


4) 로그아웃 버튼을 눌렀다. -> 눌렀지만, 내가 로그아웃 처리후 redirect를 listPage로 했기 때문에 다시 현재 화면이 뜸


5) 하지만 분명한건 로그아웃하고 다시 글등록 누르면 로그인 폼으로 이동된다는거~


여기까지해서 캐시 + 세션 + 인터셉터를 응용한 자동 로그인 구현을 마치겠습니다.


ps) 코드로 배우는 스프링 웹 프로젝트 책을 공부하고 정리한 내용임을 다시 한번 언급드립니다.

+ Recent posts