Spring MVC : 세션
1. 로그인 처리를 위한 코드 준비
이 페이지에서는 세션에 관한 내용을 설명한다. 로그인 기능을 이용해서 이 내용을 설명할 것이므로 로그인과 관련된 몇 가지 필요한 코드를 작성한다.
먼저 로그인 성공 후 인증 상태 정보를 세션에 보관할 때 사용할 AuthInfo 클래스를 다음과 같이 작성한다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
public class AuthInfo {
private Long id;
private String email;
private String name;
public AuthInfo(Long id, String email, String name) {
this.id = id;
this.email = email
this.name = name;
}
public Long getId() {
return id;
}
public String getEmail() {
return email;
}
public String getName() {
return name;
}
}
이메일과 비밀번호가 일치하는지 확인해서 AuthInfo 객체를 생성하는 AuthService 클래스는 다음과 같다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
public class AuthService {
private MemberDao memberDao;
public void setMemberDao(MemberDao memberDao) {
this.memberDao = memberDao;
}
public AuthInfo authenticate(Stirng email, Stirng password) {
Member member = memberDao.selectByEmail(email);
if(member == null) {
throw new WrongIdPasswordException();
}
if(!member.mathPassword(password)){
throw new WrongIdPasswordException();
}
return new AuthInfo(member.getId(),
member.getEmail(),
member.getName());
}
}
이제 AuthService를 이용해서 로그인 요청을 처리하는 LoginController 클래스는 다음과 같다.
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
@Controller
@RequestMapping("/login")
public class LoginController {
private AuthService authService;
public void setAuthService(AuthService authService) {
this.authService = authService;
}
@GetMapping
public String form(LoginCommand loginCommand) {
return "login/loginForm"
}
@PostMapping
public String submit(LoginCommand loginCommand, Errors errors) {
new LoginCommandValidator().validate(loginCommand, errors);
if(errors.hasErrors(){
return "login/loginForm";
})
try{
AuthInfo authInfo = authService.authenticate(
loginCommand.getEmail(),
loginCommand.getPassword());
//TODO 세션에 authInfo 저장해야 함
return "login/loginSuccess";
}catch(WrongIdPasswordException e) {
errors.reject("idPasswordNotMatching");
return "login/loginForm";
}
}
}
몇몇 class나 jsp는 생략했다.
2. 컨트롤러에서 HttpSession 사용하기
로그인 기능을 구현했는데 한 가지 빠진 것이 있다. 그것은 바로 로그인 상태를 유지하는 것이다. 로그인 상태를 유지하는 방법은 크게 HttpSession을 이용하는 방법과 쿠키를 이용하는 방법이 있다.
외부 데이터베이스에 세션 데이터를 보관하는 방법도 사용하는데 큰 틀에서 보면 HttpSession과 쿠키의 두 가지 방법으로 나뉜다.
컨트롤러에서 HttpSession을 사용하려면 다음의 두 가지 방법 중 한 가지를 사용하면 된다.
- 요청 매핑 애노테이션 적용 메서드에 HttpSession 파라미터를 추가한다.
- 요청 매핑 애노테이션 적용 메서드에 HttpServletRequest 파라미터를 추가하고 HttpServletRequest을 이용해서 HttpSession을 구한다.
2.1 메서드에 HttpSession 파라미터 추가
1
2
3
4
@PostMapping
public String form(LoginCommand loginCommand, Errors errors, HttpSession session) {
...//session을 사용하는 코드
}
요청 매핑 애노테이션 적용 매서드에 HttpSession 파라미터가 존재할 경우 스프링 MVC는 컨트롤러의 메서드를 호출할 때 HttpSession 객체를 파라미터로 전달한다.
HttpSession을 생성하기 전이면 새로운 HttpSession을 생성하고 그렇지 않으면 기존에 존재하는 HttpSession을 전달한다.
2.2 HttpServletRequest의 getSession() 메서드 이용
1
2
3
4
5
6
@PostMapping
public String submit(
LoginCommand loginCommand, Errors errors, HttpServletRequest req){
HttpSession session = req.getSession();
...// sessio을 사용하는 코드
}
두 번째 방법은 HttpServletRequestdml getSession() 메서드를 이용하는 것이다.
첫 번째 방법은 항상 HttpSession을 생성하지만
두 번째 방법은 필요한 시점에만 HttpSession을 생성할 수 있다.
2.3 HttpSession 사용
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
@Controller
@RequestMapping("/login")
public class LoginController {
...
PostMapping
public String submit(
@Valid LoginCommand loginCommand, Errors errors, HttpSession session){
if(errors.hasErrors()) {
return "login/loginForm";
}
try{
AuthInfo authInfo = authService.authenticate(
loginCommand.getEmail(), loginCommand.getPassword());
session = setAttribute("authInfo", authInfo);
return "login/loginSuccess";
}catch(IdPasswordNotMatchingException e){
errors.reject("idPasswordNotMatching");
return "login/loginForm";
}
}
}
로그인에 성공하면 17행 HttpSession의 “authInfo” 속성에 인증 정보 객체(authInfo)를 저장하도록 코드를 추가했다.
로그아웃을 위한 컨트롤러 클래스는 HttpSession을 제거하면 된다. 로그아웃 처리를 위한 LogoutController는 다음과 같다.
1
2
3
4
5
6
7
8
@Controller
public class LogoutController{
@RequestMapping("/logout")
public String logout(HttpSession session){
session.invalidate();
return "redirect:/main";
}
}
Ref.
- 최범균, 스프링프로그래밍입문5, 가메출판사.