[ 목차 ]
Cookie를 사용한 방식은 여러가지 보안 문제가 있다. 결국 보안 문제를 해결하려면 중요한 정보는 모두 서버에서 저장해야한다. Client와 서버는 예측이 불가능한 임의의 값으로 연결해야 한다.
Session
서버에서 중요한 정보를 보관하며 로그인 연결을 유지하는 방법을 Session 이라고 한다. 앞서 배운 Cookie는 중요한 정보를 Client측에서 보관하고 있는것이다.
session 생성 순서
- 로그인에 성공하면 Server에서 임의로 만든 Session ID를 생성한다.
- Session ID는 예측이 불가능해야 한다.
- UUID와 같은 값을 활용한다.
- 생성된 Session ID와 조회한 User 인스턴스를 서버의 Session 저장소에 저장한다.
- 서버에 유저와 관련된 중요한 정보를 저장한다.
session 동작 순서
- 로그인
- 상태유지를 위해 Cookie를 사용한다.
- 서버는 클라이언트에 Set-Cookie: SessionId=임의생성값 을 전달한다.
- 클라이언트는 Cookie 저장소에 전달받은 SessionId 값을 저장한다.
- Sessions을 사용하면 유저와 관련된 정보는 클라이언트에 없다.
- 상태유지를 위해 Cookie를 사용한다.
- 로그인 이후 요청
- 클라이언트는 모든 요청에 Cookie 의 SessionId를 전달한다.
- 서버에서는 Cookie를 통해 전달된 SessionId로 Session 저장소를 조회한다.
- 로그인 시 저장하였던 Session 정보를 서버에서 사용한다.
@Controller
@RequiredArgsConstructor
public class SessionUserController {
private final UserService userService;
@PostMapping("/session-login")
public String login(
@Valid @ModelAttribute LoginRequestDto dto,
HttpServletRequest request
) {
LoginResponseDto responseDto = userService.login(dto.getUserName(), dto.getPassword());
Long userId = responseDto.getId();
// 실패시 예외처리
if (userId == null) {
return "session-login";
}
// 로그인 성공시 로직
// Session의 Default Value는 true이다.
// Session이 request에 존재하면 기존의 Session을 반환하고,
// Session이 request에 없을 경우에 새로 Session을 생성한다.
HttpSession session = request.getSession();
// 회원 정보 조회
UserResponseDto loginUser = userService.findById(userId);
// Session에 로그인 회원 정보를 저장한다.
session.setAttribute(Const.LOGIN_USER, loginUser);
// 로그인 성공시 리다이렉트
return "redirect:/session-home";
}
@PostMapping("/session-logout")
public String logout(HttpServletRequest request) {
// 로그인하지 않으면 HttpSession이 null로 반환된다.
HttpSession session = request.getSession(false);
// 세션이 존재하면 -> 로그인이 된 경우
if(session != null) {
session.invalidate(); // 해당 세션(데이터)을 삭제한다.
}
return "redirect:/session-home";
}
}
@SessionAttribute
Session을 쉽게 다루도록 @SessionAttribute라는 어노테이션이 제공된다. .getSession(true)와는 다르게 Session을 새로 생성하는 기능은 없다.
이미 로그인 된 사용자를 찾는 경우(=session이 있는 경우)에 사용한다.
@Controller
@Requiredargsconstructor
public class SessionHomeController {
private UserService userService;
@GetMapping("/v2/session-home")
public String homeV2(
// Session이 필수값은 아니다. 로그인 했거나 안했거나 판별해야하니 required false
@SessionAttribute(name = Const.LOGIN_USER, required = false) UserResponseDto loginUser,
Model model
) {
// session에 loginUser가 없으면 Login 페이지로 이동
if (loginUser == null) {
return "session-login";
}
// Session이 정상적으로 조회되면 로그인된것으로 간주
model.addAttribute("loginUser", loginUser);
// home 화면으로 이동
return "session-home";
}
}
- session 정보
- session.getId();
- jsessionId 값을 조회할 수 있다.
- session.getMaxInactiveInterval();
- 세션의 유효시간
- second 단위 default는 30분(1800초)이다.
- session.getCreationTime();
- 세션 생성시간
- session.getLastAccessedTime();
- 해당 세션에 마지막으로 접근한 시간
- session.isNew();
- 새로 생성된 세션인지 여부
- session.getId();
- HttpSession 사용
- 세션 생성시점 30분이 아닌 서버에 최근 Session을 요청한 시간을 기준으로 30분을 유지한다.
- HttpSession은 기본적으로 해당 방식으로 세션의 생명주기를 관리한다.
- Session 정보에서 LastAccessedTime 을 기준으로 30분이 지나면 WAS가 내부적으로 세션을 삭제한다.
'코딩 > 자바' 카테고리의 다른 글
[Spring] filter, servlet filter (0) | 2025.02.05 |
---|---|
[Spring] Token, JWT (0) | 2025.02.05 |
[Spring] Cookie (0) | 2025.02.05 |
[Spring] Validation (1) | 2025.02.05 |
[Spring] IOC/DI, 싱글톤 패턴 (0) | 2025.02.05 |