Session이란
- 서버에서 중요한 정보를 보관하며 로그인 연결을 유지하는 방법
Cookie는 중요한 정보를 Client측에서 보관하고 있는 것
Session의 동작 방식
로그인에 성공하면 Server에서 임의로 만든 Session ID를 생성한다
- Session ID는 예측이 불가능해야 한다
- 이미 사용해보았던 UUID와 같은 값을 활용한다
생성된 Session ID와 조회한 User 인스턴스를 서버의 Session 저장소에 저장한다
- 서버에 유저와 관련된 중요한 정보를 저장한다
실제 동작방식
1. 로그인
결국 Session ID로 연결 상태유지를 위해 Cookie를 사용한다
- 서버는 클라이언트에 Set-Cookie : SessionId = 임의생성값 을 전달한다
- 클라이언트는 Cookie 저장소에 전달받은 값을 저장한다
세션의 아주 중요한 포인트는 유저와 관련된 정보는 클라이언트에 없다는것
2. 로그인 이후 요청
- 클라이언트는 모든 요청에 SessionId Cookie를 전달한다
- 서버에서는 쿠키를 통해 전달된 SessionId로 Session 저장소를 조회한다
- 로그인시 저장하였던 Session 정보를 서버에서 사용한다
정리
- Session을 사용하여 서버에서 민감한 정보들을 저장하게 되었다.
- 예상 불가능한 세션 ID를 사용하여 쿠키값을 변조해도 문제가 없다.
- Session ID가 탈취되어도 중요한 정보는 들어있지 않다.
- Session ID가 탈취되어도 시간이 지나면 세션이 만료되도록 설정 하면된다.
- Session ID가 탈취되어도 해킹이 의심되는 경우 해당 세션을 제거하면 된다.
- Session은 특별한것이 아니라 단지 Cookie를 사용하여 클라이언트가 아닌 서버에서 데이터를 저장해두는 방법이다.
- Session을 코드로 직접 구현할 수는 있지만 모두가 예상할 수 있듯이 당연히 Servlet은 Session 을 자체적으로 지원한다.
Servlet HttpSession
- HttpSession에는 Session 기능 구현에 필요한 많은 기능들을 지원한다
1. Servlet을 통해 HttpSession을 생성하게 되면 위 예시에서 본 SessionId가 JSESSIONID로 생성된다
2. JSESSIONID의 Value는 예측 불가능한 랜덤값으로 생성된다
ex) JSESSIONID = WLRMATLRKSQKA12AZKXNQ
코드예시
// 추상클래스 -> 됨
public abstract class Const {
public static final String LOGIN_USER = "loginUser";
}
// 인터페이스 -> 됨
public interface Const {
String LOGIN_USER = "loginUser";
}
// 클래스 -> 안됨
public class Const { // new Const();
public static final String LOGIN_USER = "loginUser";
}
// Const.LOGIN_USER; O / new Const(); X
@Getter
public class LoginRequestDto {
@NotBlank
private String id; // 사용자가 입력한 아이디
@NotNull
private String pwd; // 사용자가 입력한 비밀번호
}
@Controller
@Requiredargsconstructor
public class UserController {
private final UserService userService;
@PostMapping("/login")
public String login(
@Valid @ModelAttribute LoginRequestDto dto,
HttpServletRequest request
) {
User loginUser = loginService.login(dto.getId(), dto.getPwd());
// 실패시 예외처리
// 로그인 성공시 로직
// Session이 request에 존재하면 기존의 Session을 반환하고,
// Session이 request에 없을 경우에 새로 Session을 생성한다.
HttpSession session = request.getSession(); // default true => session 생성
// Session에 로그인 회원 정보를 저장한다.
session.setAttribute(Const.LOGIN_USER, loginUser);
// 로그인 성공시 리다이렉트
return "redirect:/";
}
}
- request.getSession();
- default 값은 true 이다.
- request.getSession(true);
- Request 객체 내에 Session이 존재한다면 기존 Session을 반환
- Request 객체 내에 Session이 없으면 새로운 Session을 생성해서 반환
- Default
- request.getSession(false);
- Request 객체 내에 Session이 존재한다면 기존 Session을 반환
- Request 객체 내에 Session이 없으면 null을 반환
- session.setAttribute(Const.LOGIN_USER, loginUser);
- Session에 Data를 저장하는 방법 전에 배운 request.setAttribute(); 와 비슷함
- 하나의 Session에 여러개의 데이터를 메모리에 저장할 수 있다.
로그아웃
@Controller
@Requiredargsconstructor
public class UserController {
private final UserService userService;
@PostMapping("/logout")
public String logout(
HttpServletRequest request
) {
HttpSession session = request.getSession(false);
// 세션이 존재하면 -> 로그인이 된 경우
if(session != null) {
session.invalidate(); // 해당 세션(데이터)을 삭제한다.
}
return "redirect:/";
}
}
- 로그인 후 사용할 API
- 요구사항
- 로그인한 회원이면 home 페이지로 이동(”home” 페이지를 보려면 로그인 필수)
- 로그인하지 않은 회원이면 login 페이지로 이동
- 요구사항
@Controller
@Requiredargsconstructor
public class HomeController {
private UserService userService;
@GetMapping("/")
public String home(
HttpServletRequest request,
Model model
) {
// default인 true로 설정되면 로그인하지 않은 사람들도 값은 비어있지만 세션이 만들어진다.
// session을 생성할 의도가 없다.
// session은 Memory를 사용하기 때문에 막 사용하면 안된다! 리소스 낭비!
request.getSession(false);
// session이 없으면 로그인 페이지로 이동
if(session == null) {
return "login";
}
// session에 저장된 유저정보 조회
// Object loginUser = session.getAttribute(Const.LOGIN_USER);
// 반환타입이 Object여서 Type Casting이 필요하다.
User loginUser = (User)session.getAttribute(Const.LOGIN_USER);
// Session에 유저 정보가 없으면 login 페이지 이동
if (loginUser == null) {
return "login";
}
// Session이 정상적으로 조회되면 로그인된것으로 간주
model.addAttribute("loginUser", loginUser);
// home 화면으로 이동
return "home";
}
}
'TIL' 카테고리의 다른 글
TIL 240624 Cookie (0) | 2024.06.25 |
---|---|
TIL 240621 Validation (0) | 2024.06.24 |
TIL 240617 과제 피드백 AOP (0) | 2024.06.18 |
TIL 240614 Mockito, 통합테스트 (0) | 2024.06.17 |
TIL 240613 단위 테스트 (1) | 2024.06.14 |