본 포스팅의 예제는 STS 또는 Eclipse를 사용하지 않고 Intellij를 통해 구현하고 있습니다.
그래서 기존의 STS(Spring Tool Studio)에서 생성된 Spring 프로젝트의 스프링 관련 설정 파일명과
프로젝트 구조가 약간 다를 수 있습니다.Intellij 스프링 mvc 프로젝트 생성 포스팅을 참고해주시면 감사하겠습니다.
Spring-MVC 기본 개념 및 테스트 예제 관련 포스팅 링크
순서 | 포스팅 제목 |
1 | Intellij에서 Spring MVC Project 생성하기 |
2 | Spring MVC - MariaDB 연결테스트 |
3 | Spring MVC - Mybatis 설정 및 테스트 |
4 | SpringMVC 구조 |
5 | SpringMVC + Mybatis |
6 | Spring MVC Controller 작성 연습 |
7 | Spring Interceptor |
Spring-MVC 게시판 예제 이전 포스팅 링크
1. 쿠키를 활용한 자동로그인 방식 구현
자동 로그인을 처리하기 전에 앞서 사용자가 로그인 한 후 쿠키를 만들어 브라우저로 전송하고 다시 서버에 접속할떄 쿠키가 전달되는지 확인을 먼저 해보겠습니다.
1.1 RestUserController 에서의 쿠키 생성 하기
if (loginDto.isUseCookie()) { // 로그인 유지 체크시
// 로그인 유지 유효기간 : 일주일
int amount = 60 * 60 * 24 * 7;
// 로그인 유지 유효 일자
Date sessionLimit = new Date(System.currentTimeMillis() + (1000 * amount));
// 로그인 유지 기간 갱신(아이디, 세션아이디, 유효일자)
userService.keepLogin(sessionUser.getUser_id(), session.getId(), sessionLimit);
// 로그인 쿠키 객체 생성
Cookie loginCookie = new Cookie("loginCookie", session.getId());
// 모든 경로에서 접근 가능하게 처리
loginCookie.setPath("/");
// 쿠키 유효 기간
loginCookie.setMaxAge(60 * 60 * 24 * 7);
// 쿠키 저장
response.addCookie(loginCookie);
}
위의 소스 코드를 보면 사용자가 로그인 유지를 선택한 경우 쿠키를 생성하고, loginCookie라는 이름의 변수에 현재 session의 아이디값을 보관합니다. 여기서 session 아이디는 session cookie의 값을 의미하며 session cookie의 경우 브라우저를 종료하면 사라지지만 작성하는 loginCookie의 경우 오랜시간 보관하기 위해 setMaxAge() 메서드를 활용합니다. 그리고 최종적으로 만들어진 쿠키는 HttpServletResponse에 담겨서 전송 됩니다. 위코드를 이용해서 로그인 한 후에 다른 여러 페이지에서 매번 브라우저에 loginCookie가 전달 되는 것을 개발자 도구에서 확인 할 수 있습니다.
여기서 JSESSIONID는 Tomcat에서 발행된 세션 쿠키의 이름이고 loginCookie는 사용자 요청에 의해 만들어진 쿠키입니다.
자세히 확인해보면 세션 쿠키의 값과 동일한 값이 loginCookie에 기록된 것을 확인 할 수 있습니다.
1.2 브라우저 종료 후 다시 접속
현재의 브라우저를 종료한 뒤 다시 해당 페이지를 쿠키가 유지되는 5분이내에 접속하면 아래와 같은 결과를 볼 수 있습니다.
브라우저를 종료한 뒤 다시 접속하면 JSESSION은 변경되지만 일주일간 유효기간이 지정된 쿠키는 그 값을 유지 하고 있는것을 확인 할 수 있습니다.
세션 쿠키는 브라우저가 종료될 때 같이 종료되기 때문에 매번 브라우저를 새로 실행하고, 접속하면 새롭게 만들어 집니다. 하지만 loginCookie의 경우 로그인할 떄 브라우저를 이용해서 보관 됩니다.
1.3 자동 로그인 구상
자동 로그인의 처리는 Session과 Cookie를 이요하여 처리하도록 하는데 아래와 같이 4가지의 상황이 있을 수 있습니다.
번호 | HttpSession에 sessionUser 객체의 유무 | loginCookie의 유무 | 상황 |
1 | X | X | 사용자 로그인이 필요, 비로그인 상태 |
2 | O | X | 사용자 로그인 상태(접속 중), 로그인 유지 선택 X |
3 | X | O | 이전에 로그인 한적이 있거나 7일이내에 로그인 한 적 있음 |
4 | O | O | 사용자 로그인 상태(접속 중) 로그인 유지 선택 O |
위의 4가지 상황 중에서 자동 로그인이 필요한 상황은 3번입니다. HttpSession에 sessionUser라는 이름으로 보관된 객체가 없지만 loginCookie가 존재 합니다. 이 경우는 컨트롤러에서 설정한 7일의 기간 사이에 접속한 적이 있다는 것을 의미하므로, 과거의 로그인 시점에 기록된 정보를 이용해서 다시 HttpSession에 sessionUser라는 이름으롬 UserVo 객체를 현재의 HttpSession에 보관해줘야 됩니다.
1.4 자동로그인을 위한 데이터베이스 설정 및 LoginDTO
- 사용자가 로그인하면 데이터베이스에 현재의 Session ID값과 유효기간을 저장한다.
- 사용자가 로그인하지 않은 상태에서 쿠키를 가지고 접속하면 쿠키의 내용물을 추출한다.
- 쿠키의 내용물로 데이터베이스를 조회하고, 유효기간에 맞는 값인지 검증한다.
- 확인된 사용자는 Session에 로그인한 정보를 기록해서 자동 로그인 처리를 수행 한다.
위의 내용을 구현하기 위해서 먼저 데이터베이스의 eden_user의 컬럼들을 살펴보도록 하겠습니다.
create table eden_user
(
user_no number primary key,
question_no number not null,
user_id varchar2(15) not null unique,
user_pw varchar2(200) not null,
user_nickname varchar2(30) not null unique,
user_image varchar2(200) default 'default-user-image.jpg',
user_gender varchar2(1) not null,
user_birth date not null,
user_phone varchar2(30) not null unique,
user_email varchar2(200) not null unique,
user_findAnswer varchar2(200) not null,
user_status varchar2(200) default 'active',
user_join_date date default sysdate,
user_last_connection_date date default sysdate,
sessionkey varchar2(50) default 'none',
sessionlimit date default sysdate,
constraint user_find_question_no foreign key (question_no) references eden_find_question (question_no)
);
1.5 자동로그인 영속 계층 (Persistence Tier)
src/기본패키지/user/persistence 안에 UserDAO 인터페이스와 UserDAOImpl 클래스 파일에 아래와 같이 내용을 추가 해줍니다.
// 자동 로그인
public void keepLogin(String user_id, String sessionId, Date next);
// Session Key 확인
public UserVo checkUserWithSessionKey(String value);
// 로그인 유지
@Override
@LogException
public void keepLogin(String user_id, String sessionId, Date next) {
Map<String, Object> paramMap = new HashMap<>();
paramMap.put("user_id", user_id);
paramMap.put("sessionId", sessionId);
paramMap.put("next", next);
sqlSession.update(NAMESPACE + ".keepLogin", paramMap);
}
// Session Key 확인
@Override
@LogException
public UserVo checkUserWithSessionKey(String value) {
return sqlSession.selectOne(NAMESPACE + ".checkUserWithSessionKey", value);
}
/reseoures/mappers/user 패키지안에 UserSQLMapper.xml 파일 안에 아래와 같이 내용을 추가 해주세요.
<!--로그인 유지-->
<update id="keepLogin">
UPDATE eden_user
SET
sessionkey = #{sessionId}
, sessionlimit = #{next}
WHERE user_id = #{user_id}
</update>
<!--Session Key 확인-->
<select id="checkUserWithSessionKey" resultType="UserVo">
SELECT *
FROM eden_user
WHERE sessionkey = #{value}
AND sessionlimit > sysdate
</select>
1.6 자동로그인 비지니스 계층 (Business Tier) 구현
src/기본패키지/user/service 패키지 안에 UserService 인터페이스와 UserServiceImpl 클래스에 아래와 같이 내용을 추가 해주세요.
// 로그인유지
public void keepLogin(String uid, String sessionId, Date next);
// Session Key 확인
public UserVo checkLoginBefore(String value);
// 자동로그인
@Override
@LogException
public void keepLogin(String user_id, String sessionId, Date next) {
userDAO.keepLogin(user_id, sessionId, next);
}
// Session Key 확인
@Override
@LogException
public UserVo checkLoginBefore(String value) {
return userDAO.checkUserWithSessionKey(value);
}
1.7 자동로그인 인터셉터(Interceptor) 설정
이제 마지막으로 인터셉터를 통해 사용자가 접속을 할 경우 자동으로 로그인이 되도록 처리를 해보도록 하겠습니다.
src/기본패키지/commons/interceptor 패키지안에 AutoLoginInterceptor 클래스를 생성 후 아래와 같이 내용을 작성 해주세요
public class AutoLoginInterceptor extends HandlerInterceptorAdapter {
@Autowired
private UserService userService;
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
HttpSession session = request.getSession();
Cookie loginCookie = WebUtils.getCookie(request, "loginCookie");
// 로그인 유지를 위한 쿠키가 존재하면
if (loginCookie != null) {
UserVo userVO = userService.checkLoginBefore(loginCookie.getValue());
// session에 로그인 정보 저장
if (userVO != null) {
session.setAttribute("sessionUser", userVO);
}
}
return true;
}
}
1.8 dispatcher-servlet.xml 설정
web-inf/spring/appServlet 패키지 안에 dispatcher-servlet.xml 파일 안에 아래와 같이 내용을 수정 해주세요
<!-- 로그인 권한 인증 요청 인터셉터 -->
<beans:bean id="authentication" class="com.spring.practice.commons.interceptor.AuthenticationInterceptor"/>
<!-- 자동로그인 요청 인터셉터 -->
<beans:bean id="autoLoginInterceptor" class="com.spring.practice.commons.interceptor.AutoLoginInterceptor"/>
<interceptors>
<interceptor>
<mapping path="/user/profile"/>
<beans:ref bean="authentication"/>
</interceptor>
<interceptor>
<mapping path="/**/"/>
<beans:ref bean="autoLoginInterceptor"/>
</interceptor>
</interceptors>
1.9 자동로그인 테스트 확인
2. 정리
이번에는 Session 과 Cookie 를 이용해서 자동 로그인 기능을 만들어 보았습니다. 다음에는 본격적으로 게시판을 만들어 보도록 하겠습니다.
'스프링 프레임워크 > 스프링 MVC' 카테고리의 다른 글
# Spring MVC 게시판 예제 15 : 게시글 작성 (0) | 2023.03.09 |
---|---|
# Spring MVC 게시판 예제 14 : 게시글 목록 출력 (0) | 2023.03.07 |
# Spring MVC 게시판 예제 12 : 계정 복구 (0) | 2023.03.05 |
# Spring MVC 게시판 예제 11 : 인터셉터를 활용한 권한체크 (0) | 2023.03.05 |
# Spring MVC 게시판 예제 10 : 내 프로필 페이지 구현하기 (0) | 2023.02.25 |
댓글