3 분 소요

사용자 편의를 위해 아이디를 기억해 두었다가 다음에 로그인할 때 아이디를 자동으로 넣어주는 사이트가 많다 이 기능을 구현할 때 쿠키를 사용한다.

1. 컨트롤러에서 쿠키 사용하기

예를 들어 쿠키를 사용해서 이메일 기억하기 기능을 추가한다고 하자.

이메일 기억하기 기능을 구현하는 방식은 다음과 같다.

  • 로그인 폼에 ‘이메일 기억하기’옵션을 추가한다.
  • 로그인 시에 ‘이메일 기억하기’ 옵션을 선택했으면 로그인 성공 후 쿠키에 이메일을 저장한다. 이 때 쿠키는 웹 브라우저를 닫더라도 삭제되지 않도록 유효시간을 길게 설정한다.
  • 이후 로그인 폼을 보여줄 때 이메일을 저장한 쿠키가 존재하면 입력 폼에 이메일을 보여준다.

로그인과 관련된 컨맨드 객체 클래스에 rememberEmail 필드를 추가한다.
이 필드를 사용하도록 LoginController와 loginForm.jsp를 알맞게 구현해서 이메일 기억하기 기능을 구현하겠다.

1
2
3
4
public class LoginCommand {
    private String email;
    private String password;
    private boolean rememberEmail;

이메일 기억하기 기능을 위해 추가할 코드는 다음의 세 곳이다.

  • loginForm.jsp : 이메일 기억하기 선택항목을 추가한다.
  • LoginController의 form() 메서드 : 쿠키가 존재할 경우 폼에 전달할 컨맨드 객체의 email 프로퍼티를 쿠키의 값으로 설정한다.
  • LoginController의 submit() 메서드 : 이메일 기억하기 옵션을 선택한 경우 로그인 성공 후에 이메일을 담고 있는 쿠키를 생성한다.

1.1 jsp 파일 수정

먼저 LoginForm.jsp를 수정해서 이메일 기억하기를 선택할 수 있도록 체크박스를 추가한다.

1
2
3
4
5
    <p>
        <label><spring:message code="rememberEmail" />:
        <form:checkbox path="rememberEmail"/>
        </lable>
    </p>

1.2 Controller 수정

다음 수정할 코드는 LoginController의 form() 메서드이다. form() 메서드는 이메일 정보를 기억하고 있는 쿠키가 존재하면 해당 쿠키의 값을 이용해서 loginComman 객체의 email 프로퍼티 값을 설정하면 된다.

스프링 MVC에서 쿠키를 사용하는 방법 중 하나는 @CookieValue 애노테이션을 사용하는 것이다.
@CookieValue 애노테이션은 요청 매핑 애노테이션 적용 메서드의 Cookie 타입 파라미터에 적용한다. 이를 통해 쉽게 쿠키를 Cookie 파라미터로 전달받을 수 있다.

@CookieValue 애노테이션을 사용하면 form() 메서드를 다음과 같이 구현할 수 있다.

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
import javax.servlet.http.Cookie;

import org.springframework.web.bind.annotation.CookieValue;
...

@Controller
@RequestMapping("/login")
public class LoginController {
    private AuthService authService;

    public void setAuthService(AuthService authService) {
        this.authService = authService;
    }

    @GetMapping
    public String form(LoginCommand loginCommand,
        @CookieValue(value = "REMEMBER", required = false) Cookie rCookie) {

        if(rCookie != null) {
            loginCommand.setEmail(rCookie.getValue());
            loginCommand.setRemmeberEmail(true);
        }
        return "login/loginForm";
    }
}
  • @CookieValue 속성 : value
    @CookieValue 애노테이션의 value 속성은 쿠키의 이름을 지정한다. 17행 코드는 이름이 REMEMBER인 쿠키를 Cookie 타입으로 전달받는다. 지정한 이름을 가진 쿠키가 존재하지 않을 수도 있다면 required 속성값을 false로 지정한다.

  • @CookieValue 속성 : required
    이 예제의 경우 이메일 기억하기를 선택하지 않을 수도 있기 때문에 required 속성값을 false로 지정했다. required 속성의 기본 값은 true이다. required가 true인 상태에서 지정한 이름을 가진 쿠키가 존재하지 않으면 스프링 MVC는 익셉션을 발생시킨다.

  • 쿠키 생성
    실제로 REMEMBER 쿠키를 생성하는 부분은 로그인을 처리하는 submit() 메서드이다. 쿠키를 생성하려면 HttpServletResponse 객체게 필요하므로 submit() 메서드의 파라미터로 HttpServletResponse 타입을 추가한다. 수정한 코드는 다음과 같다.

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
36
37
38
39
40
41
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletResponse;
...

@Controller
@RequestMapping("/login")
public class LoginController {
    ...

    @PostMapping
    public String submit(
            @Valid LoginCommand loginCommand, Errors errors, HttpSession session,
            HttpServletResponse response) {
        
        if(errors.hasErrors()) {
            return "login/loginForm";
        }
        try{
            AuthInfo authInfo = authService.authenticate(
                loginCommand.getEmail(),
                loginComman.getPassword());
            
            session.setAttribute("authInfo", authInfo);

            Cookie rememberCookie = 
                new Cookie("REMEMBER", loginCommand,getEmail());
            rememberCookie.setPath("/");
            if(loginCommand.isRememberEmail()){
                rememberCookie.setMaxAge(60*60*24*30);
            }else {
                rememberCookie.setMaxAge(0);
            }
            response.addCookie(rememberCookie);

            return "login/loginSuccess";
        } catch (IdPasswordNotMachingException e) {
            errors.reject("idPasswordNotMatching");
            return "login/loginForm"
        }
    }
}

13행에 HttpServletResponse 타입의 파라미터를 추가한다.
25~33행에 쿠키를 생성하거나 삭제(31행)하는 코드를 추가했다.

로그인에 성공하면 이메일 기억하기를 선택햇는지 여부에 따라(28행), 30일 동안 유지되는 쿠키를 생성하거나(29행) 바로 삭제되는(31행) 쿠키를 생성한다.

1.3 Cookie의 path 속성

쿠키의 path 속성을 이요하면 웹서버의 특정 URL에 대해서만 쿠키를 전송할 수 있다.
path 속성은 웹서버의 디렉터리 단위로 지정이 가능하며, 디렉터리를 지정하면 지정한 해당 디렉터리와 그 하위 경로에만 쿠키가 전송된다.
디렉터리 단위라는 것은 URL 경로상에 / (슬래쉬)로 구분되어지는 단위를 말한다. 쿠키1

예를 들어 다음과 같이 웹 어플리케이션의 경로가 구성된 경우 쿠키의 path 값을 /subDir1/으로 지정하면 localhost:8080/subDir1/xx.jsp 와 같이 subDir1 하위 경로로 요청시에만 쿠키가 전송된다.

만약 쿠키의 path값을 따로 설정하지 않은 경우 쿠키를 생성했던 페이지의 경로에만 쿠키가 전송된다.
예를 들어 localhostL8080/subDir2/setCookie.jsp 에서 쿠키가 생성되었다면 localhost:8080/subDir2/ 디렉터리나 그 하위 디렉터리로만 쿠키가 전송된다.

위 코드는 예제이므로 쿠키값으로 이메일 주소를 저장할 때 평문 그대로 저정했다. 하지만 이메일 주소는 민감한 개인 정보이므로 실제 서비스에서는 암호화해서 보안을 높여야 한다.

Ref.

카테고리:

업데이트: