쿠키는 장바구니, 아이디 저장과 같은 상태 정보를 유지하기 위한 기술이다.
대신 보안성이 낮기 때문에 중요한 정보를 넣는 것은 좋지 않다.
하나에 4KB 이하로 제한되어 있으며 총 300개까지 정보 저장 가능하며 최대 저장 가능 쿠키 용량은 1.2MB이다.
서버에서 쿠키를 만든다.
만든 쿠키를 응답 헤더에 보낸다.
웹 브라우저는 읽은 쿠키를 저장한다.
동일한 요청을 할 때 받은 쿠키를 서버에 보낸다.
서버는 쿠키를 보고 클라이언트가 계속 접속 상태임을 확인한다.
@CookieValue
메서드 종류
String getName() : 쿠키의 이름 리턴
String getValue() : 쿠키의 값 리턴
String getPath() : 쿠키의 적용 경로 리턴
int getMaxAge() : 쿠키의 유효기간 리턴
setValue(String value) : 쿠키의 값 설정
setPath(String path) : 쿠키가 적용되는 경로 지정
ex) setPath("/board") : board 디렉토리와 그 하위 디렉토리 / setPath("/") : 웹 애플리케이션 전체 경로에서 사용 가능
setMaxAge(int exp) : 쿠키의 유효시간을 초 단위로 설정
유효기간 미설정 시 웹 브라우저에 저장되며 브라우저를 닫으면 삭제된다.
설정 시에는 사용자의 PC에 저장되며 시간이 지나면 자동으로 삭제된다.
쿠키 생성
서버에서 쿠키 생성. response의 addCookie 메서드를 이용하여 클라이언트에게 전송
// 서버에서 쿠키 생성
Cookie cookie = new Cookie(키, 값);
// 응답에 쿠키 넣어주기
response.addCookie(cookie);
클라이언트가 보낸 쿠키 정보 읽기
쿠키는 배열로 return. 즉, 쿠키는 여러 개일 수 있다.
쿠키 값이 없으면 null로 반환. 따라서, null에 대한 처리를 해주어여함.
Cookie[] cookies = request.getCookies();
if(cookies != null) {
for(Cookie cookie : cookies) {
if("key".equals(cookie.getName())) {
find = true;
value = cookie.getValue();
}
}
}
클라이언트에게 쿠키 삭제 요청
maxAge를 0으로 설정하면 쿠키 유지 기간이 0인 쿠키가 생성된다. = 사라진다는 뜻
cookie.setMaxAge(0);
경로 이하에 모두 쿠키 적용
cookie.setPath("/");
@CookieValue 어노테이션 사용 방법
method(@CookieValue(value="쿠키이름", required=false, dafaultValue="기본값") String 변수명)
method(@CookieValue(value="REMEMBER", required=false) Cookie cookie)
로그인 예제에서 아이디를 기억하는 로직을 살펴보자.
1. LoginVO 클래스 작성
package spring;
// 로그인 정보를 담는 VO 클래스
public class LoginCommand {
private String email;
private String password;
private boolean rememberEmail; // 이메일 기억하기(쿠키 사용을 위해)
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public boolean isRememberEmail() {
return rememberEmail;
}
public void setRememberEmail(boolean rememberEmail) {
this.rememberEmail = rememberEmail;
}
}
2. loginForm.jsp
로그인 폼에 '아이디 기억하기' 영역을 추가
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
<%@ taglib prefix="spring" uri="http://www.springframework.org/tags" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title><spring:message code="login.title"/></title>
</head>
<body>
<form:form commandName="command"> <!-- controller 요청 파라미터와 맞추기 -->
<p>
<label>
<spring:message code="email"/>:
<form:input path="email"/>
<form:errors path="email"/>
</label>
</p>
<p>
<label>
<spring:message code="password"/>:
<form:input path="password"/>
<form:errors path="password"/>
</label>
</p>
<p>
<label>
<spring:message code="rememberEmail"/> <!-- LoginCommand 필드명과 맞추기 -->
<form:checkbox path="rememberEmail"/>
</label>
</p>
<input type="submit" value="<spring:message code="login.btn"/>">
<form:errors/>
</form:form>
</body>
</html>
3. label.properties에 메세지 추가
rememberEmail=아이디 기억하기
4. LoginController 작성
package controller;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import org.springframework.stereotype.Controller;
import org.springframework.validation.Errors;
import org.springframework.web.bind.annotation.CookieValue;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import spring.AuthInfo;
import spring.AuthService;
import spring.IdPasswordNotMatchingException;
import spring.LoginCommand;
import spring.LoginCommandValidator;
@Controller
@RequestMapping("/login")
public class LoginController {
private AuthService authService;
public void setAuthService(AuthService authService) {
this.authService = authService;
}
@RequestMapping(method=RequestMethod.GET)
public String form(
@ModelAttribute("command") LoginCommand loginCommand,
@CookieValue(value="REMEMBER", required=false) Cookie cookie) { // 요청에서 쿠키를 확인하기 위한 방법
if(cookie != null) { // 이미 쿠키가 있으면 (재접속 혹은 쿠키가 유지되는 시간일 경우에 해당)
loginCommand.setEmail(cookie.getValue()); // 쿠키의 값을 가져와서 email에 넣어줘
loginCommand.setRememberEmail(true); // 쿠키가 존재한다
}
// 쿠키가 있던 없던 로그인 폼으로 이동
return "login/loginForm";
}
@RequestMapping(method=RequestMethod.POST)
public String submit(
@ModelAttribute("command") LoginCommand loginCommand,
Errors errors, HttpSession session,
HttpServletResponse response) { // 응답 생성
new LoginCommandValidator().validate(loginCommand, errors); // 유효성 검사
if(errors.hasErrors()) { // 에러가 발생하면 = 아이디나 비번이 비어있으면
return "login/loginForm"; // 다시 로그인 폼으로
}
try {
AuthInfo authInfo = authService.authentication(
loginCommand.getEmail(),
loginCommand.getPassword());
session.setAttribute("authInfo", authInfo); // 인증 정보 세션에 저장
// 쿠키 생성
Cookie rememberCookie = new Cookie("REMEMBER", loginCommand.getEmail());
rememberCookie.setPath("/"); // 해당 경로를 요구할 때만 쿠키를 보내게 함
if(loginCommand.isRememberEmail()) { // isRememberEmail()이 true면 = 쿠키가 존재하면
rememberCookie.setMaxAge(60); // (60*60*24*30)
}else { // isRememberEmail()이 false면
rememberCookie.setMaxAge(0); // 쿠키 삭제
}
response.addCookie(rememberCookie); // 쿠키 전송
return "login/loginSuccess"; // 로그인 성공 페이지로 이동
} catch(IdPasswordNotMatchingException e) { // 예외가 발생하면
errors.reject("idPasswordNotMatching"); // 에러 처리
errors.reject("required");
return "login/loginForm";
}
}
}
'SPRING' 카테고리의 다른 글
mybatis 환경설정 : <typeAliases> (0) | 2020.10.15 |
---|---|
스프링 유효성 검증 : @Valid 어노테이션 (0) | 2020.10.15 |
HandlerInterceptor : 세션을 미리 확인하자 (0) | 2020.10.12 |
로그인 / 로그아웃 / 세션 (0) | 2020.10.12 |
비밀번호 변경하기 (0) | 2020.10.12 |