세션과 쿠키
Session | Cookie |
사용자 데이터를 저장하는 역할 | |
데이터를 서버에 저장 브라우저 단위로 생성되며, 브라우저가 종료되면 세션에 있는 데이터도 사라진다. |
데이터를 사용자의 PC(로컬)에 저장 데이터의 유효기간 설정이 가능하여, 브라우저가 종료되더라도 유효기간 동안은 데이터를 계속 사용할 수 있다. |
UserController
1
2
3
4
5
6
7
8
9
10
11
12
13
|
@ResponseBody
@PostMapping("/signin")
public ModelAndView signinPost(ModelAndView mv, UserVO user) {
UserVO dbUser = userService.signin(user);
if(dbUser != null)
mv.setViewName("redirect:/");
else
mv.setViewName("redirect:/signin");
mv.addObject("user", dbUser); //Interceptor(postHandler)에게 전송할 user 정보
return mv;
}
|
cs |
LoginInterceptor
- Servlet-context.xml에서 로그인 컨트롤러와 연결되어 있음
1
2
3
4
5
6
7
|
<beans:bean id="loginInterceptor" class="com.ysy.bakingdom.interceptor.LoginInterceptor" />
<interceptors>
<interceptor>
<mapping path="/signin"/>
<beans:ref bean="loginInterceptor"/>
</interceptor>
</interceptors>
|
cs |
- 로그인버튼을 클릭하고 컨트롤러에서 setViewName을 실행하기 직전에 작동하는 인터셉터(postHandle)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
|
public class LoginInterceptor extends HandlerInterceptorAdapter {
@Autowired
UserService userService;
//로그인 완료 후 실행할 인터셉터
@Override
public void postHandle(
HttpServletRequest request, HttpServletResponse response, Object handler,
ModelAndView modelAndView) throws Exception {
//Controller의 mv에서 addObject로 "user"를 전달해 왔을 때 실행. 전달값이 없으면 null로 설정됨.
UserVO user = (UserVO)modelAndView.getModelMap().get("user");
if(user != null) {
//리퀘스트에 있는 세션 정보 가져오기
HttpSession session = request.getSession();
//세션에 user 정보 추가
session.setAttribute("user", user);
//자동로그인에 체크가 되어있으면
if(user.getUseCookie() != null) {
// 여기서 getId는 SessionId를 의미한다.
Cookie autoLoginCookie = new Cookie("autoLoginCookie", session.getId());
// 쿠키를 찾을 경로
autoLoginCookie.setPath("/");
// 쿠키 유지 시간 ( sessionLimit)
autoLoginCookie.setMaxAge(60*60*24*30);
response.addCookie(autoLoginCookie);
Date user_sessionLimit = new Date(System.currentTimeMillis() + (amount * 1000L));
userService.keepLogin(user.getUser_email(), session.getId(), user_sessionLimit);
}
}
}
}
|
cs |
- Controller에서 addObject로 담아보낸 user데이터를 받아옴.
- user데이터가 있으면 (로그인이 가능하면), 세션에 user데이터를 담아 저장한다.
=== 자동로그인에 체크되어 있을 때 == - useCookie 값이 null이 아니면 (로그인 할 때 자동로그인에 체크했으면)
새로운 쿠키(autologincookie)를 생성하여 현재 세션에 저장되어 있는 세션아이디를 쿠키에 담는다. - 모든 URL범위에서 쿠키를 전송할 수 있도록 경로를 설정해준다. (setpath)
- 저장된 쿠키의 유효기간을 설정해준다.
- 30일동안 유효 : 60초 60분 24시간 * 30일 => 60*60*24*30
- currentTimeMillis()는 long 타입으로 값을 반환한다. 여기에 60*60*24*30*1000을 연산하여 값을 보내주면 int값으로 계산되어 int타입을 벗어나 오버플로우가 발생한다. 따라서 1000L로 계산하여 연산 값을 long타입으로 만들어줘야한다. (int 범위 : –2,147,483,648 ~ 2,147,483,647 , 60*60*24*30*1000 =2,592,000,000) - response.addCookie에 쿠키데이터를 실어서 응답.
- 아까 실려온 user데이터에서의 email과 세션데이터에 담겨져 있는 세션id, 그리고 오늘날짜로부터의 유효기간을 담아 Service에게 keepLogin을 시킨다.
- UserService
1
|
void keepLogin(String user_email, String user_sessionId, Date user_sessionLimit);
|
cs |
- UserServiceImp
1
2
3
4
5
6
7
|
@Override
public void keepLogin(String user_email, String user_sessionId, Date user_sessionLimit) {
if(user_email == null || user_sessionId == null || user_sessionLimit == null)
return;
userDao.keepLogin(user_email, user_sessionId, user_sessionLimit);
}
|
cs |
- UserDAO
1
|
void keepLogin(@Param("user_email") String user_email, @Param("user_sessionId") String user_sessionId, @Param("user_sessionLimit") Date user_sessionLimit);
|
cs |
- UserMapper
1
2
3
4
5
6
|
<update id="keepLogin">
update user set
user_sessionId = #{user_sessionId},
user_sessionLimit = #{user_sessionLimit}
where user_email = #{user_email}
</update>
|
cs |
AutoLoginInterceptor
- servlet-context.xml에서 모든 url 경로와 연결되어 있다. = 모든 페이지변경마다 AutoLoginInterceptor가 작동된다.
<interceptors>
<interceptor>
<mapping path="/signin"/>
<beans:ref bean="loginInterceptor"/>
</interceptor>
<interceptor>
<mapping path="/**/"/>
<beans:ref bean="autoLoginInterceptor"/>
</interceptor>
</interceptors>
|
cs |
- url 경로를 따라 컨트롤러로 진입하기 직전에 작동되는 인터셉터(preHandle)
public class AutoLoginInterceptor extends HandlerInterceptorAdapter {
@Autowired
UserService userService;
// url이동시 컨트롤러에 진입하기 전에 실행되는 인터셉터
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception {
// 현재 세션 데이터를 가져온다.
HttpSession session = request.getSession();
// 세션에 담겨진 user정보를 VO타입으로 담는다.
UserVO user = (UserVO)session.getAttribute("user");
// 만약 세션에 담겨진 user정보가 없으면,
if(user == null) {
Cookie autoLoginCookie = WebUtils.getCookie(request, "autoLoginCookie");
if(autoLoginCookie!=null) {
user = userService.getUserByCookie(autoLoginCookie.getValue());
if(user != null) {
session.setAttribute("user", user);
}
}
}
return true;
}
}
|
cs |
- 세션에 "user"로 전달 받은 유저 데이터를 가져와 VO타입 user에 저장한다.
- 만약 세션에 담겨진 "user" 정보가 없으면
(= 로그인되지 않은 상태 or 세션유효기간이 만료되어 자동로그인이 종료된 상태 or 자동로그인이 아닌 상태)
해당 user의 로그인 관련 쿠키 상태를 확인하기 위해, request에서 "autoLoginCookie"를 가져온다. - 가져올 autoLoginCookie 정보가 없으면 (autoLoginCookie==null) 인터셉터 작동 종료.
- 가져올 autoLoginCookie가 있으면, 해당 Cookie 값(세션아이디)을 가지는 유저 데이터를 찾아 VO user에 저장한다. 유저 데이터가 정상적으로 존재하면 세션 정보를 user로 설정한다.
- 위 내용을 매 페이지마다(경로 변경마다) 작동하며 로그인을 유지시킨다.
- UserService
UserVO getUserByCookie(String user_sessionId);
|
cs |
- UserServiceImp
@Override
public UserVO getUserByCookie(String user_sessionId) {
return userDao.getUserByCookie(user_sessionId);
}
|
cs |
- UserDAO
UserVO getUserByCookie(String user_sessionId);
|
cs |
- UserMapper
<select id="getUserByCookie" resultType="com.ysy.bakingdom.vo.UserVO">
select * from user where user_sessionId = #{user_sessionId} and user_sessionLimit > now()
</select>
|
cs |
- user_sessionLimit이 현재 시간보다 클 경우 (유효기간이 남아있을 경우)에만 검색된다.
'SPRING > 연습장' 카테고리의 다른 글
Interceptor 동작 경로 설정 (0) | 2021.08.24 |
---|---|
form안의 데이터를 한 번에 묶어 ajax로 전송하기 (0) | 2021.08.17 |
jsp에서 보낸 이메일 주소가 controller에서 잘려 받아질 때 (0) | 2021.08.10 |
코딩용 폰트 비교 (0) | 2021.08.08 |
MySQL Workbench를 이용한 DB 원격 접속 방법 (0) | 2021.08.06 |