[Web] 쿠키와 세션

HTTP는 Stateless 한 프로토콜

HTTP 프로토콜은 Stateless 방식이라 이전의 웹페이지 정보 알 수 없음.
로그인 같은 이전 기록 사라지는 문제.

이전 웹페이지 데이터 사용하는법
1. 쿠키 : 클라이언트 PC에 Cookie 파일에 정보 저장 후 웹페이지 간 공유

  1. 세션 : 서버 메모리에 정보 저장 후 웹페이지 간 공유.

쿠키

쿠키란 웹 페이지 간 공유할 정보를 클라이언트 PC에 저장해놓고 사용하는 방법.

  • 클라이언트 PC에 저장됨.
  • 저장 용량 제한 있음(4kb)
  • 보안이 취약함
  • 클라이언트 브라우저에서 사용 유무 결정 가능
  • 도메인 별로 쿠키가 생성됨.
  • javax.servlet.http.Cookie 사용.
  • Response객체의 addCookie()로 클라이언트에게 쿠키 전송 후 저장
  • Request객체의 getCookie()로 클라이언트의 쿠키 가져옴.

지속 쿠키 vs 세션 쿠키
지속 쿠키는 파일로 생성. 삭제나 설정값 종료시까지 보존. 클라이언트의 설정 저장 등을 위한 쿠키.
세션 쿠키는 브라우저 메모리에 생성. 브라우저 종료시까지 보존. 서버가 세션 구분 하기 위한 쿠키.

쿠키 순서

  1. 클라이언트가 서버에 최초 접속.
  2. 서버는 response에 쿠키담아서 응답.
  3. 클라이언트의 다음 request부터 쿠키 담아서 송신.
  4. 서버는 아까 그 클라이언트라는 것을 인지할 수 있음.

쿠키 생성자

Cookie c = new Cookie(이름, 값);

쿠키 유효기간 정하기

c.setMaxAge(유효기간);

쿠키를 서버에서 클라이언트로 전송하기

response.addCookie(c);

클라어인트의 모든 쿠키를 가져오기

쿠키를 가져올때는 반드시 모든 쿠키를 배열로 가져와야함.

Cookie[] allcookies = request.getCookies();

클라이언트에게서 가져온 쿠키의 이름과 값 가져오기

이름 : allcookies[i].getName()
값 : allcookies[i].getValue()

인코딩 및 디코딩

쿠키에는 아스키코드(영,숫자)만 가능. 한글은 인코딩 및 디코딩 필요

String 변수 = URLEncoder.encode(값, 인코딩 이름);
String 변수 = URLDecoder.decode(값, 인코딩 이름);

쿠키 실습

protected void doGet(HttpServletRequest request, HttpServletResponse response) 
throws ServletException, IOException {
        response.setContentType("text/html;charset=utf-8");
        PrintWriter out = response.getWriter();
        Date d = new Date();
        Cookie c = new Cookie("cookieTest", URLEncoder.encode("JSP프로그래밍입니다.", "utf-8"));
        //쿠키 객체 생성. 쿠키 이름은 cookieTest. 쿠키내용은 한글을 utf-8로 인코딩해서 저장.

        c.setMaxAge(24 * 60 * 60); //쿠키의 유효기간 생성.
        //c.setMaxAge(-1);  //세션 쿠키를 생성할 경우.
        response.addCookie(c); // 생성된 쿠키를 브라우저로 전송해줌.
        out.println("현재시간 : " + d);
        out.println("<br> 문자열을 Cookie에 저장합니다.");

    }

SetCookie 서블릿.
Cookie 생성자에서 쿠키의 이름과 값을 입력해준다.
한글의 경우 utf-8로 인코딩해야하므로 URLEncoder 사용.
쿠키 유효기간 정해주지 않을 시 세션 쿠키가 된다.

protected void doGet(HttpServletRequest request, HttpServletResponse response) 
throws ServletException, IOException {
        response.setContentType("text/html;charset=utf-8");
        PrintWriter out=response.getWriter();
        Cookie[] allValues=request.getCookies(); //브라우저의 쿠키값 배열로 전달받음.
        for(int i=0; i<allValues.length;i++){
            if(allValues[i].getName().equals("cookieTest")){ //해당 쿠키의 이름이 cookieTest인 것의 값 출력
                out.println("<h2>Cookie 값 가져오기 : "+URLDecoder.decode(allValues[i].getValue(),"utf-8"));
            }
        }

    }

GetCookie 서블릿
브라우저의 쿠키를 배열로 가져온 뒤 특정이름의 쿠키 찾아 값 출력


세션

쿠키는 공유정보를 클라이언트 PC에 저장하나.
세션은 서버 메모리에 저장하여 보안면에서 유리 -> 로그인 등에 사용

  • 정보가 서버의 메모리에 저장
  • 세션 쿠키를 이용(쿠키 이름 : JSESSIONID).
  • 최초 세션 생성시 서버는 세션 쿠키를 응답에 담아 전송. 클라이언트는 서버에 요청마다 해당 쿠키를 담아 전송한다.
  • 브라우저(사용자) 당 한 개의 세션. JSESSIONID 쿠키를 통해 사용자를 구분한다.
  • 보안에 유리하나 서버에 부하
  • 유효 시간 가짐(기본 30분)
  • 로그인 유지 & 쇼핑몰 장바구니 등에 사용

세션 순서

  1. 클라이언트가 서버에 최초 접속.
  2. 서버는 세션 객체 생성. JSESSIONI 쿠키를 response에 담아 클라이언트에게 전송
  3. 클라이언트는 다음 요청시마다 JSESSIONID 쿠키 함께 전송.
  4. 서버는 해당 JSESSIONID 쿠키 값을 보고 매핑되는 세션 객체에서 정보 확인

즉 서버의 각 세션 객체에 초기 설정한 같은 변수명으로 저장된다. user, user_pw과 같이.
이때 세션을 구분하기 위해 JSESSIONID 라는 세션쿠키를 사용한다.

서버에서 클라이언트 세션 가져오기

Httpseesion session = request.getSession();
->해당 클라이언트의 세션이 존재한다면 세션 객체를. 존재하지 않는다면 세션 객체 새로 생성하여 반환.

request.getSession(false);
-> 세션이 존재하면 세션 객체를. 존재하지 않는다면 null을 반환

최초 생성된 세션인지 : session.isNew()

세션에 바인딩하기

Httpsession 객체도 ServletContext 객체처럼 바인딩하여 사용가능.
setAttribute나 getAttribute 메서드 활용

세션 아이디 및 접근 시각 가져오기

세션 아이디 : session.getId()
최초 세션 객체 생성 시각 : new Date session.getCreateTime()
가장 마지막 세션 접근 시각 : new Date session.getLastAccessedTime()
세션 객체 유효 시간 : session.getMaxInactiveInterval()

세션 완전히 삭제

session.invalidate();

세션 이용 로그인 구현

  • 로그인 HTML
  • 로그인 서블릿
  • DAO, VO
  • 로그인 성공시 정보조회 서블릿 (session 존재하는지 판별하여 수행)
  1. 로그인 화면 HTML로 구현. form 태그로 입력 ID, PWD를 로그인 서블릿으로 넘겨줌.
  2. 로그인 서블릿은 ID, PWD 받아서 VO 객체에 저장. DAO 객체 생성해서 isExisted() 메서드 수행
  3. DAO의 isExisted 메서드는 쿼리문을 통해 DB에 해당 ID와 PWD를 갖는 데이터가 있는지 확인하여 서블릿에게 반환
  4. 로그인 서블릿은 isExisted 결과가 True라면 세션 생성 및 세션 객체에 로그인 정보와 ID,PWD 바인딩
  5. 정보조회 서블릿은 request.getSession(false)를 세션 객체를 받아옴. 세션이 null이 아니라면 바인딩된 로그인 정보를 출력.

/*Login Servlet*/
private void doHandle(HttpServletRequest request, HttpServletResponse response)
	throws ServletException, IOException {
        request.setCharacterEncoding("utf-8");
        response.setContentType("text/html;charset=utf-8");
        PrintWriter out = response.getWriter();
        String user_id = request.getParameter("user_id");
        String user_pwd = request.getParameter("user_pwd");

        MemberVO memberVO = new MemberVO();
        memberVO.setId(user_id);
        memberVO.setPwd(user_pwd);
        MemberDAO dao = new MemberDAO();
        boolean result = dao.isExisted(memberVO); //dao에서 쿼리문 수행

        if (result) {
            HttpSession session = request.getSession(); //세션 생성
            session.setAttribute("isLogon", true); // 로그인 정보 바인딩
            session.setAttribute("login.id", user_id);
            session.setAttribute("login.pwd", user_pwd);

            out.print("<html><body>");
            out.print("안녕하세요 " + user_id + "님!!!<br>");
            out.print("<a href='show'>회원정보보기</a>"); //회원 정보 조회 서블릿으로
            out.print("</body></html>");
        }
/*정보 조회 서블릿*/
protected void doGet(HttpServletRequest request, HttpServletResponse response) 
	throws ServletException, IOException {
        response.setContentType("text/html;charset=utf-8");
        PrintWriter out = response.getWriter();
        String id ="", pwd="" ;
        Boolean isLogon=false;
        HttpSession session =  request.getSession(false); //세션이 있는지 확인

        if( session != null){ // 있다면 세션에 바인딩 된 정보 출력
            isLogon=(Boolean)session.getAttribute("isLogon");
            if(isLogon==true){
                id = (String)session.getAttribute("login.id");
                pwd = (String)session.getAttribute("login.pwd");
                out.print("<html><body>");
                out.print("아이디: " + id+"<br>");
                out.print("비밀번호: " + pwd+"<br>");
                out.print("</body></html>");
            }else{
                response.sendRedirect("login3.html");
            }
        }else{
            response.sendRedirect("login3.html");
        }
    }

좋은 웹페이지 즐겨찾기