동일한 user의 computer라 하더라도 session, cookie는 브라우저가 다르면 다르게 관리한다. cookie, session은 브라우저가 관리한다.
네트워크 연결성
Spring 환경에서 Cookie 다루는 법
1. Severlet의 HttpServletResponse 객체 사용
2. CookieValue("key") 사용
package com.lec.spring.controller5;
import jakarta.servlet.http.Cookie;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;
import java.io.IOException;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
@Controller
@RequestMapping("/cookie")
public class CookieController {
// 클라이언트로부터 온 request 안의 cookie 정보들 조회
@RequestMapping("/list")
public void list(HttpServletRequest request, Model model){
// 클라이언트 안의 쿠키 정보는 request 시에 서버로 전달된다.
// request.getCookies() 로 쿠키 받아올수 있다.
Cookie[] cookies = request.getCookies();
StringBuffer buff = new StringBuffer();
if(cookies != null){ // 쿠키가 하나도 없다면 null 을 리턴한다
for (int i = 0; i < cookies.length; i++) {
// Cookie 는 name-value 쌍으로 이루어진 데이터 (name, value 는 모두 String)
String name = cookies[i].getName();
String value = cookies[i].getValue();
buff.append((i + 1) + "] " + name + " : " + value + "<br>");
}
} else {
buff.append("쿠키가 없습니다<br>");
}
model.addAttribute("result", buff.toString());
}
// 쿠키 생성 절차
//1. 쿠키(Cookie) 클래스로 생성
//2. 쿠키속성 설정(setter)
//3. 쿠키의 전송 (response 객체에 탑재:addCookie())
@RequestMapping("/create")
public String create(HttpServletResponse response) throws IOException {
String cookieName1 = "num1";
String cookieValue1 = "" + (int)(Math.random() * 10);
Cookie cookie1 = new Cookie(cookieName1, cookieValue1); // name-value 쌍으로 Cookie 생성
cookie1.setMaxAge(30); // 쿠키 파기(expiry) 시간 설정 (생성 시점으로부터 30 초 후)
response.addCookie(cookie1); // response 에 Cookie 추가
// 쿠키는 얼마든지 생성 가능
String cookieName2 = "datetime";
String cookieValue2 = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddhhmmss"));
Cookie cookie2 = new Cookie(cookieName2, cookieValue2);
cookie2.setMaxAge(45);
response.addCookie(cookie2);
// response.sendRedirect("/cookie/list");
return "redirect:/cookie/list";
}
@RequestMapping("/delete")
public String delete(HttpServletResponse response){
String cookieName = "num1"; // 삭제할 cookie 의 name
Cookie cookie = new Cookie(cookieName, "");
cookie.setMaxAge(0); // response 되자마자 해당 name 의 cookie 는 삭제됨.
response.addCookie(cookie);
return "redirect:/cookie/list";
}
@RequestMapping("/num1")
@ResponseBody
public String num1(@CookieValue(value = "num1", required = false) Cookie cookie){
if(cookie != null){
return cookie.getName() + " : " + cookie.getValue();
}
return "num1 쿠키 없어요";
}
//------------------------------------------------------------------------
public static final String ADMIN_ID = "admin";
public static final String ADMIN_PW = "1234";
@GetMapping("/login")
public void login(@CookieValue(name="username", required = false) String username, Model model){
model.addAttribute("username", username);
}
@PostMapping("/login")
public String loginOk(String username, String password, HttpServletResponse response, Model model){
// username /password 일치하면 인증성공 -> 쿠키 발급
if(ADMIN_ID.equalsIgnoreCase(username) && ADMIN_PW.equals(password)){
Cookie cookie = new Cookie("username", username);
cookie.setMaxAge(30);
response.addCookie(cookie);
model.addAttribute("result", true);
} else {
Cookie cookie = new Cookie("username", username);
cookie.setMaxAge(0); // 기존에 혹시 있었을 쿠키도 삭제한다.
response.addCookie(cookie);
}
return "cookie/loginOk";
}
@PostMapping("/logout")
public String logout(HttpServletResponse response){
Cookie cookie = new Cookie("username", "");
cookie.setMaxAge(0); // 기존에 혹시 있었을 쿠키도 삭제한다.
response.addCookie(cookie);
return "cookie/logout";
}
}
Spring이 session을 다루는 법
1. HttpSession object 사용
2. @SessionAttribute 사용
3. Model에 저장 시, session, request에 저장 (RedirectAttribute도 내부적으로 session 사용)
package com.lec.spring.controller5;
import jakarta.servlet.http.HttpSession;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Enumeration;
@Controller
@RequestMapping("/session")
public class SessionController {
// HttpSession 객체
// 현재 request 한 client 에 대한 Session 정보
// session 은 attribute(name-value쌍) 들이 담겨 있다
// name: String 타입, value: Object 타입
@RequestMapping("/list")
public void list(HttpSession session, Model model){
Enumeration<String> enumeration = session.getAttributeNames();
StringBuffer buff = new StringBuffer();
int i = 0;
while(enumeration.hasMoreElements()){
String sessionName = enumeration.nextElement();
// session.getAttribute('name') <-- 특정 세션 attr value 추출. 리턴타입 Object. 해당 name 이 없으면 null 리턴
String sessionValue = session.getAttribute(sessionName).toString();
buff.append((i + 1) + "] " + sessionName + " : " + sessionValue + "<br>");
i++;
}
if(i == 0){
buff.append("세션 안에 attribute 가 없습니다<br>");
}
model.addAttribute("result", buff.toString());
}
@RequestMapping("/create")
public String create(HttpSession session){
String sessionName, sessionValue;
sessionName = "num1";
sessionValue = "" + (int)(Math.random() * 100);
// 세션 attr : name-value 생성
// setAttribute(String name, Object value) 두번째 매개변수는 Object 타입이다
session.setAttribute(sessionName, sessionValue);
sessionName = "datetime";
sessionValue = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd hh:mm:ss"));
session.setAttribute(sessionName, sessionValue);
return "redirect:/session/list";
}
@RequestMapping("/delete")
public String delete(HttpSession session){
// removeAttribute(name) 세션 attribute 삭제
session.removeAttribute("num1");
return "redirect:/session/list";
}
//-------------------------------------------------
public static final String ADMIN_ID = "admin";
public static final String ADMIN_PW = "1234";
@GetMapping("/login")
public void login(HttpSession session, Model model){
// 현재 로그인 상태인지, 즉 로그인 세션 (name이 'username'인 세션값)이 있는지 확인
if(session.getAttribute("username") != null){
model.addAttribute("username", session.getAttribute("username"));
}
}
@PostMapping("/login")
public String loginOk(String username, String password, HttpSession session
, Model model){
// 세션 name-value 지정
String sessionName = "username";
String sessionValue = username;
// 제출된 id /pw 값이 일치하면 로그인 성공 + 세션 attr 생성
if(ADMIN_ID.equalsIgnoreCase(username) && ADMIN_PW.equals(password)){
session.setAttribute(sessionName, sessionValue);
model.addAttribute("result", true);
}else{
session.removeAttribute(sessionName);
}
return "session/loginOk";
}
@PostMapping("/logout")
public String logout(HttpSession session){
String sessionName = "username";
// 세션 삭제
session.removeAttribute(sessionName);
return "session/logout";
}
}