ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [JSP] 007. 쿠키(Cookie)와 세션(Session)
    SsY/Class 2023. 5. 25. 18:00
    728x90
    ※ 해당 실습을 진행하는 동안 실행 시 F5(새로고침)이 아닌 Ctrl+F11 로 새 창을 띄운다

    쿠키(Cookie)와 세션(Session) 의 개념
    - WebApp13
    ■■■ 쿠키(Cookie)와 세션(Session) ■■■
    ○ 쿠키(Cookie)
       - 쿠키는 클라이언트에 대한 정보를 클라이언트의 하드디스크에
         작은 파일 형태로 저장한 text 파일로
         서버에서 사용자에게 편리한 기능을 제공하기 위해 많이 사용되고.
         쿠키는 웹 브라우저에 의해 관리된다.
         //-- 현재는 순수 txt 파일이라고 하기 어렵다. 
         //-- 브라우저마다 쿠키를 저장하는 방법과 운용정책 등이 계속 변함-> 확인이 어려워짐
    
       - 쿠키는 텍스트 형태로 저장되기 때문에 변조나 복사 등이 가능하여 보안성이 취약하고
         클라이언트에... 예전에는 총 300개 까지 저장 가능했으며, 
         각 도메인 당 갯수 제한(20개)이나 크기 제한(4096Byte)은
         사실상 무의미해져 가고 있다.
         //-- ★클라이언트에 보관 -> 보안 취약
         //-- 위와 같이 관리방식이 달라졌으나 클라이언트에 보관한다는 그 자체로 보안성 취약함은 변하지 않음
         //-- 사실상 개수, 용량 제한이 없고 (설정을 통해서 지정가능) 대부분 무제한으로 쓰고 있다고 생각하면 됨
    
       - 저장되는 위치는 시스템(운영체제)이나 브라우저에 따라 다르며
         일반적인 형식(계정명@도메인)도 지속적으로 바뀌어가고 있다.
         //-- 예전엔 운영체제가 지정한 하나의 폴더등에 줄세워져서 관리가 되었으나 현재는 그렇지 않음
    
       - 쿠키는 웹 브라우저가 거쳐간 웹 사이트 및 개인의 정보가 기록되기 때문에
         개인의 사생활을 침해할 소지가 있으며,
         이로 인한 보안 문제를 유발하기 때문에 일반적으로 웹 브라우저 자체에
         쿠키 거부 기능이 포함되어있다.
         하지만, 쿠키 거부 기능을 설정하게 되면 웹 브라우저와의 연결을 
         지속시키지 못하기 때문에 문제가 발생하게 된다.
         (사실상 거부하는 의미가 없음... 반 강제적)
         //-- 예전에는 광고들이 대상도 명확하지 않고, 얼마나 접근했는지 등이 명확하게 확인이 불가능했지만
         //-- 현재는 확인이 가능 -> 쿠키정보를 통해 정보를 파악해 브라우저 회사들이 광고 회사등에 제공하여 이득을 보는 경우도 있음
         //-- 따라서 현재도 많은 논의가 되고 있는 부분이기도 하다.
    -----------------------------------------------------------------------------------------------------------------------------------
       - 쿠키의 동작 방식 (※접은글1)
         쿠키의 동작 방식은 웹 서버와 웹 브라우저 간의 상호 협력으로 이루어진다.
         웹 서버가 웹 브라우저의 요청에 응답할 때
         http 프로토콜에 있는 http 헤더에 쿠키 정보를 포함시켜 클라이언트 쪽으로 보낸다.
         그리고 웹 브라우저가 웹 서버에 존재하는 페이지를 요구할 때
         그 전에 자신이 방문했을 때 해당 페이지에 대해 웹 서버가 웹 브라우저 쪽으로
         심어놓았던 쿠키를 웹 서버로 다시 건네주어서
         이전 상태를 웹 서버가 알 수 있도록 한다.
    -----------------------------------------------------------------------------------------------------------------------------------
       - 쿠키(객체)의 파라미터(속성)
          ·name=value
            : 쿠키는 반드시 이름을 포함해야 한다.
              이름은 변수명과 같은 목적으로 사용된다.
    
          ·expires=date
            : 유효기간을 지정한다.
              날짜를 생략할 경우 브라우저 종료 시점까지 쿠키가 남아있게 된다.
              유효기간 설정은 그리니치 표준시(Wdy, DD-Mon-TT HH:MM:SS GNT)로 설정하게 된다.
          ·path=path
            : 웹 서버에서 쿠키 값이 디렉터리 간에 유효한 범위를 설정하는 것으로
              path 값은 웹 서버의 document root 를 기준으로 설정한다.
              예를 들어... path 가 『/』 이면 (『"path=/;"』)
              도메인의 루트(/) 에서 시작하는 모든 곳을 접속할 때
              해당 쿠키의 값을 적용할 수 있다.
              생랼할 경우 현재 문서의 위치와 디렉터리와 하위 디렉터리가
              쿠키의 범위가 된다.
          ·domain=domain()
            : 한 사이트에서 만든 쿠키가 다른 사이트에 영향을 주지 않기 때문에
              도메인 항목이 필요하다.
              도메인은 자동으로 사이트의 기본 도메인으로 설정된다.
          ·secure
            : 데이터의 전송에 보안이 요구되는지를 지정한다
              true 는 브라우저가 안전하다고 판단하는 서버만 나타나게 된다.
              기본값(default)은 false 이다.
    -----------------------------------------------------------------------------------------------------------------------------------
       - 쿠키의 기본 설정
          ① Cookie 객체 생성
             Cookie c = new Cookie("쿠키이름","쿠키값");
          ② Cookie 객체 설정
             c.setMaxAge(쿠키 유효시간 초 단위 설정);
          ③ Cookie 객체 등록(추가)
             response.addCookie(c);
    -----------------------------------------------------------------------------------------------------------------------------------
       - JSP 에서 쿠키를 설정하는 방법은 두 가지가 있다.
         첫 번째 방법은
         『response』 객체에 『setHeader()』 메소드를 이용하여 쿠키를 설정하는 것이다.
         하지만, 권장하지 않는다.
         ex) response.setHeader("set_cookie","name=value, expires=value, ...");
             //-- 이 방법은...
             //   Header 에 key와 값, key와 값, ... 을 String type 으로 넘기는 것이기 때문에
             //   엄밀히 말하자면 쿠키라는 객체를 넘기는 것이 아니다.
             //   과거에는 쿠키라는 클래스가 존재하지 않았기 때문에
             //   이 방법을 이용했었다.
    
         두 번째 방법은
         『Cookie』 클래스를 이용하는 방법이다.
         ·String getComment()
           : 쿠키에 대한 설명을 가져온다.
         ·String getDomain()
           : 쿠키가 유효한 도메인 정보를 가져온다.
         ·int getMaxAge()
           : 쿠키의 유효한 시간 정보를 가져온다.
         ·String getName()
           : 쿠키의 이름을 가져온다.
         ·String getPath()
           : 쿠키의 유효한 디렉터리 정보를 가져온다.
         ·String getSecure()
           : 쿠키의 보안 설정 값을 가져온다.
         ·String getValue()
           : 쿠키의 해당 값을 가져온다
         ·String getVersion()
           : 쿠키의 버전 값을 가져온다.
         ·void setComment(String purpose)
           : 쿠키에 대한 설명을 설정한다.
         ·void setDomain(String pattern)
           : 쿠키에 대한 유효한 도메인 정보를 설정한다.
         ·void setMaxAge(int expiry)
           : 쿠키에 대한 유효한 시간 정보를 설정한다.
         ·void setSecure(String url)
           : 쿠키의 보안 설정값을 구성한다.
         ·void setValue(String newValue)
           : 쿠키의 해당 값을 설정한다.
         ·void setVersion(int v)
           : 쿠키의 버전 값을 설정한다.
    -----------------------------------------------------------------------------------------------------------------------------------
       - JSP 에서 쿠키(Cookie) 유효시간 설정
         『setMaxAge(int expiry)』 메소드를 통해 유효시간을 설정한다.
         ·『expiry』가 『음수』 일 때
           : 브라우저가 종료되면 쿠키가 제거된다.
         ·『expiry』가 『0』 일 때
           : 생성과 동시에 쿠키가 제거된다.
         ·『expiry』가 『양수』 일 때
           : 초 단위로 해당 시간만큼 쿠키가 유지된다.
         『setMaxAge()』 메소드를 통해 유효시간을 설정하지(명시하지) 않은 경우
           기본적으로 음수가 설정되어 브라우저가 종료될 때까지 쿠키가 유지된다.
    ============================================================================================
    ○ 세션(Session)
    //-- 은행어플 타이머, 오늘 하루 이 창 보지 않기 등에 대표적으로 사용되고 있다.
    
       - 쿠키의 경우 브라우저에 상태를 유지하기 위한 정보를 저장하지만
         (즉, 로컬 PC 의 하드디스크에 저장)
         세션은 웹 서버의 웹 컨테이너에 상태를 유지하기 위한 정보를 저장하는 것으로
         『javax.servlet.http』 패키지의 『HttpSession』 인터페이스를 통해
         세션을 사용하게 된다.
         또한, 세션은 서버와 관련된 정보를 노출하지 않기 때문에
         쿠키를 사용하는 것 보다 『HttpSession』 인터페이스의 세션을 통한 상태 관리가
         보다 안정적(보안성 향상)이라 할 수 있다.
    -----------------------------------------------------------------------------------------------------------------------------------
       - Session 생성
         Session 을 생성하기 위해서는 페이지 디렉티브(page directive)의
         Session 속성을 true 로 설정한다.
         (별도로 설정하지 않아도 자동으로 기본값 적용.
          즉, 사용하지 않을 경우만 false 로 설정.)
         ex) <%@ page session='true' %>
    -----------------------------------------------------------------------------------------------------------------------------------
       - Session 내장 객체의 주요 메소드
         ·String getId()
           : Session 의 고유 ID 값을 구한다.
             (『세션아이디』라고 한다. 세션 고유 ID 를 문자열 형태로 반환한다.)
         ·long getCreationTime()
           : 세션이 생성된 시간을 구한다.
             (시간은 1970년 1월 1일 이후 흘러간 시간을 의미한다.)
         ·long getLastAccessedTime()
           : 웹 브라우저가 가장 마지막에 세션에 접근한 시간을 구한다.
         ·int getMaxInactiveInterval()
           : 세션 유지 시간을 초로 반환한다. 기본값은 30분으로 지정된다.
         ·void setMaxInactiveInterval(int interval)
           : 세션을 유지할 시간을 interval 에 설정된 초 값으로 설정한다.
         ·void invalidate()
           : 현재 세션을 종료한다.
             세션과 관련된 모든 값을 삭제한다.
         ·boolean isNew()
           : 클라이언트의 『세션아이디』를 할당하지 않은 경우 『true』값을 반환한다.
             새로운 세션인지의 여부를 확인할 때 사용한다.
         ·void setAttribute(String key, Object value)
           : 주어진 key 속성의 값을 value 로 지정한다.
         ·Object getAttribute(String key)
           : 주어진 key 속성의 값을 얻어낸다.
         ·void removeAttribute(String key)
           : 주어진 key 속성의 값을 제거한다.
    -----------------------------------------------------------------------------------------------------------------------------------
       - 한 번 생성된 세션은 종료하기 전까지 지속적으로 유지된다
         (중간에 사라지지 않음)
          단, 은행 인터넷 뱅킹 이용 시 로그인이 풀리는 것과 같은 이유는
          임의로 설정을 해 두었기 때문이다.
          이와 같은 성격으로 웹 어플리케이션을 실행하는 동안
          지속적으로 사용하는 데이터의 저장 장소로는 세션이 적합(적당)하다.
          //-- 클라이언트 하나 당 한 세션
    -----------------------------------------------------------------------------------------------------------------------------------
    ※ 참고
        - 스코프(scope) → 대부분의 교재에서 life of cycle(생명주기)로 설명함.
          웹 어플리케이션은 page, request, session, application 이라는
          4개의 영역(객체)를 가지고 있으며
          기본 객체의 영역은 객체의 유효기간이라고도 불리며,
          객체를 누구와 공유할 것인가를 나타낸다
          ·page 영역
             한 번의 웹 브라우저(클라이언트)의 요청에 대해
             하나의 JSP 페이지가 호출되며
             웹 브라우저의 요청이 들어오면
             이 때... 단 한개의 페이지만 대응된다.        
          ·request 영역
             한 번의 웹 브라우저(클라이언트)의 요청에 대해
             같은 요청을 공유하는 페이지가 대응되며
             웹 브라우저의 한 번의 요청이 단지 한 개의 페이지만 요청될 수 있고
             같은 request 영역이면 두 개의 페이지가 같은 요청을 공유한다.
             (include 액션 태그, forward 액션 태그 사용 시)
          ·session 영역
             하나의 웹 브라우저 당 한 개의 Session 객체가 생성된다.
             같은 웹 브라우저 내에서는 요청되는 페이지들이 같은 객체를 공유한다.
          ·application 여역
             하나의 웹 어플리케이션 당 한 개의 application 객체가 생성된다.
             대부분의 환경 설정에서 사용된다.
             같은 웹 어플리케이션에서 요청되는 페이지들은 같은 객체를 공유한다.

     

    더보기

    ※ 쿠키의 접근 방식 (상상)

    내가 어떤 페이지에 처음  url 을 통해서 진입
    -> 서버에서 나한테 쪽지를 하나 (대놓고 or 슬쩍) 툭하고 주머니에 넣어놓음
    -> 내가 해당 페이지에서 칫솔, 치약을 들었다놨음
    -> 이러한 내용이 시간부터 제품 정보들까지 넣어놓은 쪽지에 다 기록이 됨
    -> 집에 돌아왔을 때 보면 쪽지가 주머니에 있음
    -> 며칠뒤, 다시 해당 페이지에 접근하면
    -> 서버가 내 주머니를 뒤져서 쪽지를 뒤져봄 (쪽지의 유무로 처음방문/재방문을 확인)
    -> 그 쪽지에 따라서 안내를 해주는 것을 할 수 있음

    주머니 = 쿠키 , 쪽지 = 쿠키 
    저장되는 공간도 쿠키
    저장되는 파일도 쿠키
    사용하는 문법도 쿠키 등.. 다 쿠키라고 불러버림..


    • TestSession01
      & TestSession01_ok
      & Logout
    • TestSession01
    <%@ page contentType="text/html; charset=UTF-8"%>
    <%
    	// TestSession01_ok.jsp 페이지에서
    	// 이 페이지를 다시 요청할 수 있도록 안내하면서
    	// session 의 userId 에 superman 을.. userName 에 이준복을 담아서 보낸 상황
    	String userId = (String)session.getAttribute("userId");
    	String userName = (String)session.getAttribute("userName");
    	//-- 『session.getAttribute("userId")』는
    	//    Object 타입을 반환하므로
    	//    String 타입으로 변환하는 과정 필요(다운 캐스팅)
    	
    	// 추가!!
    	// 세션 시간 변경 설정 -------------------------------------------------
    	
    	// ※ 세션 기본(default) 시간은 1800 초
    	
    	session.setMaxInactiveInterval(5);
    	//-- 세션이 유지되는 시간을 5초로 설정한 상태
    	//   이로 인해...
    	//   로그인 후 10초 동안 아무 액션도 없는 상태에서...
    	//   다시 페이지 새로고침을 수행하면 로그아웃 처리된 것을 확인할 수 있다.
    	
    	//  ------------------------------------------------- 세션 시간 변경 설정 
    	
    %>
    <!DOCTYPE html>
    <html>
    <head>
    <meta charset="UTF-8">
    <title>TestSession01.jsp</title>
    <link rel="stylesheet" type="text/css" href="css/MemberScore.css">
    <style type="text/css">
    	a {text-decoration: none;}
    	.btnMenu
    	{
    		border: 1px solid grey;
    		border-radius: 3px;
    		font-size: 8pt;
    		width: 60px;
    		height: 20px;
    	}
    </style>
    
    <script type="text/javascript">
    
    	function sendIt()
    	{
    		// 확인
    		//alert("함수 호출 확인");
    		
    		//var f = document.getElementById("myForm");
    		// id 지정 하지 않을 시 위와 같이 불가능. name으로 아래와 같은 방식으로 불러올 수 있다.
    		var f = document.myForm;
    		
    		// input element name 태그로 가져오는 방법
    		if (!f.userId.value)
    		{
    			alert("아이디를 입력해야합니다.");
    			f.userId.focus();
    			return;
    		}
    		
    		if (!f.userPwd.value)
    		{
    			alert("패스워드를 입력해야합니다.");
    			f.userPwd.focus();
    			return;
    		}
    		
    		f.submit();
    	}
    
    </script>
    
    </head>
    <body>
    
    <div>
    	<h1>세션 처리 - 로그인</h1>
    	<hr />
    </div>
    
    <div>
    	<table>
    		<tr>
    			<td>
    				<a href="">
    					<button type="button" class="btnMenu btn01">게시판</button>
    				</a>|
    				
    			<%
    			if (userId==null)
    			{
    			%>
    				<a href="">
    					<button type="button" class="btnMenu btn02" disabled="disabled">일정관리</button>
    				</a>|
    				<a href="">
    					<button type="button" class="btnMenu btn02" disabled="disabled">친구관리</button>
    				</a>|
    			<%
    			}
    			else
    			{
    			%>
    				<a href="Sce.jsp">
    					<button type="button" class="btnMenu btn01" >일정관리</button>
    				</a>|
    				<a href="Fri.jsp">
    					<button type="button" class="btnMenu btn01" >친구관리</button>
    				</a>|
    			<%
    			}
    			%>
    			
    			</td>
    		</tr>
    	</table>
    </div>
    <br><br>
    <div>
    	<table>
    		<tr>
    			<td>
    				<%
    				if (userId==null)
    				{
    				%>
    				<form action="TestSession01_ok.jsp" method="post" name="myForm">
    					<table>
    						<tr>
    							<th>아이디</th>
    							<td>
    								<input type="text" name="userId" class="txt" style="width: 150px;">
    							</td>
    						</tr>
    						<tr>
    							<th>패스워드</th>
    							<td>
    								<!-- <input type="password"> -->
    								<input type="text" name="userPwd" class="txt" style="width: 150px;">
    							</td>
    						</tr>
    						<tr>
    							<td colspan="2">
    								<button type="button" class="btn" style="width: 100%;"
    								onclick="sendIt()">로그인</button>
    							</td>
    						</tr>
    					</table>
    				</form>
    				<%
    				}
    				else
    				{
    				%>
    				<h2><%=userName %>(<%=userId %>)님, 환영합니다.</h2>
    				<h2>이제, 일정관리와 친구관리 서비스를 이용할 수 있습니다.</h2>
    				<p>
    					<a href="Logout.jsp">
    						<button type="button" class="btnMenu btn01">로그아웃</button>
    					</a>
    				</p>
    				<%
    				}
    				%>
    			</td>
    		</tr>
    	</table>
    </div>
    
    
    </body>
    </html>
    
    <!-- 게시판은 모든 사용자(로그인 필요X)가 이용할 수 있으며, 일정관리와 친구관리만 로그인 필요 --> 
    <!-- 유효한 ID, PW 가지고 로그인 -> 성공 -->

    • TestSession01_ok
    <%@ page contentType="text/html; charset=UTF-8"%>
    <%
    	// TestSession01_ok.jsp
    	
    	// 이전페이지(TestSession01.jsp)로부터 데이터 수신
    	// → userId, userPwd
    	String userId = request.getParameter("userId");
    	String userPwd = request.getParameter("userPwd");
    	
    	// DTO 구성 → 로그인 관련 테이블의 데이터와 비교(DAO 활용) → 최종적으로 로그인 액션 처리
    	// 12~14 문은 위의 실습편의상 생략하여 아래와같이 데이터를 얻었다는 가정하게 진행
    	String tblMemberId = "superman";
    	String tblMemberPwd = "123456";
    	String tblMemberName = "준복리";
    	
    	if (userId.equals(tblMemberId) && userPwd.equals(tblMemberPwd))
    	{
    		// 로그인 액션 처리 -- 세션 값 채우기
    		session.setAttribute("userId", userId);				//-- userId - superman
    		session.setAttribute("userName", tblMemberName);	//-- userName - 준복리
    		
    		// 클라이언트가 페이지를 다시 요청할 수 있도록 안내
    		response.sendRedirect("TestSession01.jsp");
    	}
    
    	/* 로그인 실패시 해당 페이지에 머물게 하기 위해서 else 별도 구성 X */
    		
    %>
    <!DOCTYPE html>
    <html>
    <head>
    <meta charset="UTF-8">
    <title>TestSession01_ok.jsp</title>
    <link rel="stylesheet" type="text/css" href="css/MemberScore.css">
    </head>
    <body>
    
    <h1>로그인 실패~</h1>
    
    <a href="TestSession01.jsp">로그인 페이지로 돌아가기~!!!</a>
    <!-- 같은 페이지로 돌아가게 되나 세션이 채워져있지 않다는 차이점이 있다. -->
    </body>
    </html>

    • Logout
    <%@ page contentType="text/html; charset=UTF-8"%>
    <%
    	// Logout.jsp
    	//-- 세션의 내용을 없애서 로그아웃 처리
    	
    	// 스코프가 영향을 미치기 때문에 아래와 같이 사용 가능
    	//session.getAttribute("userId");
    
    	// 항목별 제거
    	session.removeAttribute("userId");
    	session.removeAttribute("userName");
    	//-- 세션의 사용자 아이디와 패스워드 사용자 이름 제거
    	
    	// 기존 세션에 저장되어 있는 모~~~~~든 항목을 제거하고
    	// 세션을 초기화
    	//session.invalidate();
    	
    	//-- 즉 항목별이나 초기화 둘, 중 하나만 사용해도 됨.
    	
    	// 클라이언트에게 다시 로그인 페이지를 요청할 수 있도록 안내
    	response.sendRedirect("TestSession01.jsp");
    	
    %>
    <!DOCTYPE html>
    <html>
    <head>
    <meta charset="UTF-8">
    <title>Logout.jsp</title>
    <link rel="stylesheet" type="text/css" href="css/main.css">
    </head>
    <body>
    
    </body>
    </html>

    해당 과정에서 DTO, DAO, DBConn은 실습 편의상 임으로 구성하여 사용하는 것으로 처리
    HttpSession 으로 생성
    세션은 스코프 영역이 request 객체와 달리 넓게 사용이 가능하다

    728x90
Designed by planet-si