HTTP(상태 비저장 프로토콜)는 요청을 보낼떄마다 클라이언트가 누구인지 매번 확인해야하는 특성을 보안하기 위해 쿠키 와 세션을 사용한다.
쿠키,세션?
둘다 웹에서 사용되고, 뭔가를 저장 한다는 공통점이 있다.
개발자는 웹을 만들 떄 , 어떤 정보를 쿠키에 저장할지 세션에 저장할지 잘 판단을 해여한다.
🍪쿠키란?
쿠키는 브라우저에서 데이터를 저장하는 방식중 하나입니다.
쿠키란 비유하자면 => 찜질방 손목열쇠. 시설을 이용할떄마다 보여줘야된다.
단, 단점으로는 내 브라우저에 저장됨으로써 해킹,조작 등등 쉽게 노출될수 있기떄문에 민감한 정보는 쿠키에 저장하지 않는다.
즉 사용자의 편의에 의해서 간단한 정보들을 브라우저에 저장할떄 사용된다
=> 로그인시 아이디 자동완성, 로그인 없이 쇼핑몰 장바구니 등의 정보 저장할떄 사용된다.
👅세션이란?
중요하고 민감한 정보로 사용자가아닌 서버에서 직접 관리하 해야 하는 정보들을 세션으로 서버 내에서 다룬다.
예시 ) 사용자 아이디, 비밀번호
1. 세션을 사용하는 사이트에 접속하면 서버에서는 사용자를 구분하기 위한 기한의 짦은 임시키, 즉 세션 키를 브라우저에 보내서 쿠키로 저장한다.
2. "얄코"란 사용자가 사이트 안의 페이지를 돌아다닐떄 이 사용자의 중요한 정보들은 이 서버의 메모리나 데이터베이스에 저장된다
3.브라우저가 이 사이트의 페이지들에 접속할떄 마다 http 요청에 이 세션 키를 실어서 전송하고, 서버는 그 세션 키를 보고 "애는 얄코구나"를 인식해서 얄코의 정보들을 가공해서 응답을 보내준다.
세션은 서버에 부하가 많음으로 잘 사용해야 한다. (아래에 세션 관리 참고)
🍪처리 진행 과정
아래 부터는 쿠키와 세션을 직접 생성해서 실습을 해보는 예제를 만들어봤다.
🍪쿠키 직접 생성해보기
@Controoler
@PostMapping("/login")
public String login(String id, String pwd, boolean rememberId,HttpServletResponse response) throws IOException {
//1. id와 pw를 확인
if(!loginCheck(id,pwd)) {
String msg = URLEncoder.encode("id또는 비밀번호를 잘못입력하셨습니다.", "utf-8");
//2-1일치하지 않으면 , loginForm으로 이동
return "redirect:/login/login?msg="+msg;
}
//아이디기억 체크박스에 체크 되있을경우
if(rememberId) {
// 쿠키생성
Cookie cookie = new Cookie("id",id);
cookie.setMaxAge(60*52*24);
response.addCookie(cookie);
}
// 체크박스에 체크되지 않았을 경우
else {
Cookie cookie = new Cookie("id",id);
cookie.setMaxAge(0); //쿠키 유효시간 0으로 설정
response.addCookie(cookie);
}
//2-2. id와 pw가 하면 않으면 홈으로 이동
return "redirect:/";
}
private boolean loginCheck(String id, String pwd) {
return "asdf".equals(id)&& "1234".equals(pwd);
}
loginForm,jsp
cookie.id.value로 쿠키에 있는 값을 꺼낸다.
👅 세션 실습 - (게시판 이용시, 미로그인이면 로그인 화면으로 이동)
BoardController
@Controller
@RequestMapping("/board")
public class BoardController {
@GetMapping("/list")
public String list(HttpServletRequest request) {
//로그인 안했으면 로그인 화면으로이동
if(!loginCheck(request)) {
return "redirect:/login/login;
}
// 로그인을 한 상태이면 , 계시판 화면으로 이동
return "boardList";
}
private boolean loginCheck(HttpServletRequest request) {
// 1. 세션을 얻어서
HttpSession session = request.getSession();
// 2. 세선에 id가 있는지 확인, 있으면 true를 반환함
// if(session.getAttribute("id")!=null)
// return true;
// else
// return false;
//널이아니면 true 반호
return session.getAttribute("id")!=null;
}
}
클라이언트가 board/list를 요청을 하면 세션을 통해 로그인 체크여부를 확인한다 -> session.getAttribute() 세션에 저장된 값이 있는지 없는지 확인하고 없으면 -> reidrect:/login/lgon/ 로그인 화면으로 리다이렉트 하도록 만들었다.
request를 필요로 한다. loginCheck와 상위 메서드에 request추가 (HttpServletRequest request)
LoginController
//2-2.
아이디 유효성 체크 코드 생략 ...............
유효성 체크 통과하면
//세션 객체를 얻어오기
HttpSession session = request.getSession();
// 세션 객체에 id를 저장
session.setAttribute("id", "asdf");
//아이디기억 체크박스에 체크 되있을경우
if(rememberId) {
// 1.쿠키생성
Cookie cookie = new Cookie("id",id);
cookie.setMaxAge(60*52*24);
response.addCookie(cookie);
}
// 체크박스에 체크되지 않았을 경우
else {
Cookie cookie = new Cookie("id",id);
cookie.setMaxAge(0); //쿠키 유효시간 0으로 설정
response.addCookie(cookie); //쿠키를 통해 브라우저에 쿠키와 세션id 보냄
}
아이디 유효성 체크를 하고 -> request에서 세션 객체를 얻어온다음 id값을 저장한다.
loginController의 response(쿠키생성된 곳) 에 세션을 request로 넣어준다 .
LoginController
@GetMapping("/logout")
public String logOut(HttpSession session) {
//1. 세션을 종료
session.invalidate();
//2. 홈으로 이동
return "redirect:/";
}
사용자가 로그아웃 버튼을 누르면 session.invalidate()를 사용해서 세션을 종료 시킨다
index.jsp
로그인시 상단바에 고정값이 아니라, EL로 변동값을 받을 수 있도록 한다.
👅 로그인 처리후 이동 경로 (최초 요청했던 경로로 이동하기)index.jsp (x) - >/board/list(o)
기능구현은 끝났지만,하지만 로그인시 메인페이지 index.jsp 가 아닌 클라이언트가 최초 요청했던 /board/list로 갈수있도록 해주어야한다 .! 최초 요청했던 값을 로그인시 같이 넘겨줘야한다 .
BoardController
@Controller
@RequestMapping("/board")
public class BoardController {
@GetMapping("/list")
public String list(HttpServletRequest request) {
//로그인 안했으면 로그인 화면으로이동
if(!loginCheck(request)) {
return "redirect:/login/login?toURL="+request.getRequestURL(); //값을 넘김
}
return "redirect:/login/login?toURL="+request.getRequestURL(); //최초 요청했던 값을 가져와서 리다이렉트로 같이넘겨준다.
LogtinForm.jsp
로그인 폼양식 생략......
......
<input type="text" name="id" value="${cookie.id.value}" placeholder="이메일 입력" autofocus>
<input type="password" name="pwd" placeholder="비밀번호">
<input type="hidden" name="toURL" value="${param.toURL}" placeholder="비밀번호">
리다이렉트로 최초 요청했던 경로가 같이 넘어온것을 확인할수있고. 그리고 로그인 폼에 input 타입을 추가하고, hidden 으로 처리해서 같이 post로 방식으로 요청 값을 LoginController 에게 보낸다.
LoginController
@PostMapping("/login")
public String login(String id, String pwd, String toURL,boolean rememberId, HttpServletRequest request,
HttpServletResponse response) throws Exception {
로그인 유효성 체크 생략 ...
toURL = toURL==null || toURL.equals("")? "/": toURL; //toURL 넘어온값이 제대로 안넘어오거나 빈문자열이면 -> 메인페이지 반환 , 빈문자열이 아닌경우 ->toURL안에있는 값으로 이동
return "redirect:"+toURL;
}
파라미터로 String toURL을 받고, 유효성 체크가 끝나고 로그인 성공시, 우리가 최초 요청했던 /board/list화면으로 리다이렉트 하면 끝.!
👅세션 관리
세션은 생성되면 서버에 부담을 줌으로써, 가능하면 필요할떄만 효율적이게 사용하는게 좋다.
세션이 필요하지 않는 페이지에는 <%@ page session="false"%> 값을 주면 세션이 생성되지않는다.
로그인후 세션이 생성되고 세션 false값을 준 페이지를 들어가도 세션은 삭제되지 않는다.
참고
1.스프링의 정석 남궁성
2. https://ala-nueva.tistory.com/189
'Develop > CS' 카테고리의 다른 글
[CS] 문자열 Encoding이란? 아스키코드,유니코드, UTF-8 개념정리 (0) | 2025.02.17 |
---|---|
[CS] HTTP 메서드 PUT,PATCH 차이점 및 종류 (0) | 2025.02.15 |
[Web]Servlet&JSP, Model1/Model2방식 차이와 스프링MVC (1) | 2025.01.22 |
Web Server 와 WAS 차이와 웹 서비스 구조 (0) | 2024.02.18 |