쿠키를 통해서 세션아이디와 일치하는, '자동로그인 했던 회원의 정보' 를 불러온 뒤 다시한번 세션에 저장해버리는 로직을 구현 하기위해, 불러온 회원 정보를 어딘가에 재활용 할수있도록 보관해야합니다. 바로 DB에 보관해야합니다. DB에 쿠키의 만료시간과 쿠키의 값을 함께 저장하겠습니다. sql을추가해서 컬럼을 2개 추가합니다.
자동로그인 하지 않은사람은 default값으로 none이 저장 됩니다. 다음으로는 VO에는 DB에추가한 컬럼을 필드에 추가한 후
setter()/getter() 와 toString()을 새롭게추가 합니다.
이곳의 sessionId는 쿠키에 저장된 sessionId입니다.
아이디를 기준으로 쿠키에 저장된 sessionId 와 세션유효시간을 저장해줍니다.
회원정보가 insert 되어있는 상태에서, 로그인 할때 자동로그인을 체크안하면 session_id 값은 none이 됩니다. 반대로 체크를 한다면 none을 자동로그인 쿠키값에 담겨있는 세션아이디로 변경됩니다. 이때, limitTime또한 null에서
시간으로 수정해줘야합니다. 컨트롤러의 로그인을 수행하는 로그인메서드에서 날짜객체를 저장하는 로직을 추가합니다.
limitTime 같은경우엔 초단위로 계산했기 때문에 날짜로 바꿔서 넣어야합니다.
limitTime을 밀리초로바꿉니다.
하지만 이것은 딱 3개월이라는 날짜일 뿐이며 3개월 후에 사라지게 하기 위해서는 날짜객체자체를 지금으로부터 3개월 후의 기간으로 만들어야 하기때문에
현재시간을 밀리초단위로 구하는 메서드를 호출하여 3개월에 더해줍니다. limitTime을 밀리초로 바꾸고 현재시간을 더해서 롱타입 변수에 저장합니다.
이것이 지금으로부터 3개월 후가 되는 초단위 시간입니다. 삼개월 후의 시간이 초단위 이므로 다시 날짜로 바꾼 후 날짜객체에 저장합니다.
DB에 세션정보와 시간 전달합니다.
매개변수로 들어가는 session.getId()는 로그인 요청이 들어오면서 이미 쿠키에 저장된 sessionId값입니다 지금까지 한 작업은 쿠키에 저장되는 sessionId를 DB에도 저장해 주기 위한 작업의 진행과정 입니다. 로그인 요청할때 동시에 작업이 이루어 지는것 이기 때문에 두 값이 같게되는 것입니다. 이제 service와 service클래스에 메서드를 추가한 후 컨트롤러와 Mapper인터페이스를 연결합니다.
service클래스
매퍼 xml에서 session_id=#{}, limit_time=#{}, account=#{} 셋 모두 VO에 있어서 VO객체를 통으로 전해줘도 되겠지만 클라이언트가 sessionId를 넘겨주진 않았습니다. 직접 조회를하고 쿠키에 넣어줬던 작업 기억하시죠?
그렇기 때문에 service메서드에는 mapper에 들어갈 값들을 객체로 넣을수 없기때문에 컨트롤러에서 호출할때와 같이 각개로 넣어줍니다. 하지만! 시험해보기위해 자동로그인을 체크하고 로그인을 수행했을때 BindingException:이라는 오류가 발생할 것입니다. [arg2, arg1, arg0, param3, param1, param2]즉, 전달되는 데이터의 순서를 정해달라는것입니다.
mapper에서는 다량의 데이터를 즉, 매개변수가 두개이상을 담아 넘긴다면 한군데에 묶여있어야 합니다 객체로 포장해야한다는 것과 같습니다.
Service클래스에서 Mapper에게 전달할 때 각개적으로 주지않고 한군대에 묶어줍니다.
HashMap을사용해서 Mapper xml파일의 쿼리문에 #{ }에 들어갈 이름을 map의 key이름과 맞춰 넣어주면 되겠습니다. 이제 다시 서버를 실행하고 자동로그인 체크박스에 체크후 로그인을 진행해 보면 DB에 sessionId값과 session유효기간에 대한 값이 성공적으로 들어간걸 확인할 수 있습니다.
로그아웃을 할때는 sessionID를 지워버려서 다시 디폴트값인 None으로 만들어야만 합니다 그렇다면 이제 쿠키값과 동일한 값을 가진 회원이 1명 존재합니다 쿠키를통해 회원정보를 읽을수있는 작업을 로직을 작성 하겠습니다.
쿼리문을 mapper에 입력해줍니다.
그렇다면 재방문시 로그인을 어떻게 유지시킬것인가 다시 사이트에 진입하는데 진입하자마자 특정한 세션아이디를 읽어들입니다, 이전 자동 로그인에 대한 세션ID가 저장된 쿠키의 기록입니다. 쿠키로부터 읽어들인 세션아이디를 가지고 DB에게 물어봅니다 로그인이라는이름으로. 우리는 이제 이 작업을 인터셉터를 활용하여 작업 할것입니다.
인터셉터로 작업될 로직이 완료되었다면 해당 인터셉터를 빈등록 하고 인터셉터 설정을 합니다.
서버를 실행하고 메인페이지에 접속이 됬을 때 새로운 아이디로 접속해보는 실습을 진행합니다. 기존 저장되있는 쿠키를 삭제하고 새로운 아이디로 자동로그인 요청을 보내면서 로그인을 시도해야 합니다. F12개발툴을 누른 후 Ctrl+Shift+DELETE키를 눌러주면 쿠키를 삭제할 수 있습니다. 쿠키를 지우는 이유는 로그아웃을 눌러도 다시 홈으로 돌아갔을 때 컨트롤러 접근 이전에 쿠키를 확인하고 자동로그인을 시켜주는 인터셉터에 또 걸려버리므로, 로그아웃이 진행되지 않습니다. 쿠키를 지운다면 인터셉터에서 쿠키가 비어있지않을 때 로그인처리가 되는 if조건문 로직으로 넘어가지 않게되겠죠? 쿠키가 지워졌을때 새로운 아이디를 자동로그인으로 로그인 해주게되면 인터셉터에서 로컬로부터 쿠키값을 읽은 후 쿠키가 비여있으므로 컨트롤러로 넘어간 뒤 새로운 세션ID값이 쿠키에 등록이됨과 동시에 로그인을 시도한 새로운 아이디에 세션아이디와 세션의유효시간을 DB에 한번 더 저장해줍니다. 이렇게 쿠키를 지워주는 작업을 로그아웃 메서드에서 처리 해줘야합니다. 로그아웃 로직 순서로는
로그아웃 시 자동로그인 쿠키 삭제 및 해당 회원 정보에서 session_id 제거 1. loginCookie를 읽어온 뒤 해당 쿠키가 존재하는지 여부 확인
쿠키의 수명을 0초로 다시 설정한 후 (setMaxAge)
작업으로 쿠키를 삭제하게 되는것입니다. 유효기간이 0초이기때문에 저렇게 세팅하고 브라우저에서 로그아웃처리를 해 주는 순간 0초가 지나버리기 때문에 로컬에서 쿠키가 삭제됩니다.
Session에 저장되어있는 정보중 회원 아이디 user.getAccount();를 기준으로 세션의 시간을 현재 시간으로 고쳐줘야하고 쿠키를 "none"으로 저장하여 삭제합니다.
따지고보면 제기준에서는 로그아웃에 의한 쿠키삭제 처리가 더 우선적으로 진행된 후 인터셉터 처리를 하는게 맞지 않나 싶습니다. 인터셉터를 먼저 설정해버린다면 흐름파악이 조금 꼬이게될지도 모릅니다. 중간에 쿠키를 삭제할때 로그아웃 했을때 쿠키가 삭제되는 행위를 컨트롤러단에서 하지 않고 임의적으로 쿠키를 삭제를 해 버리기 때문에 개념 흐름이 조금 모호해질수 있습니다. |