쿠키(cookie)는 우리가 일상 생활에서 과자인 쿠키와 비슷합니다.
과자인 쿠키를 먹다보면 흘리게 되는 경우가 대부분입니다.
쿠키를 먹은 흔적을 남긴다고도 할 수 있는데 프로그래밍에서도 쿠키는 흔적을 남기는 것입니다.
서버와 클라이언트가 연결을 시도한 흔적을 남겼다가 나중에는 흔적을 가지고 접속을 했었는지 아닌지를 구분 할 수 있습니다.
우리가 사용하는 프로토콜은 http프로토콜입니다.
http 프로토콜은 특징이 있습니다.
브라우저가 요청하고 서버가 응답을 하면서 연결을 하게 됩니다.
브라우저가 데이터를 요청하면 서버는 가공을 하게 되는데 가공을 하고나서 응답을 하게 되겠지요.
한번 요청을하고 응답을 하면 클라이언트와 서버간의 연결을 해제해버립니다.
하나의 서버에 수많은 클라이언트가 있기 때문에 모든 클라이언트의 연결을 유지시키게 되면 리소스가 낭비되면서 과부화가 오게됩니다.
그래서 한번 요청이 오면 응답하고나서 해제를 하고 다시 또 요청이 오면 다시 응답하는 식으로 효율적으로 운영을 하기 때문에 연결을 바로바로 해제한다고 할 수 있습니다.
그런데 이러한 방식은 문제가 생길수도 있습니다.
예를 들어, 온라인 쇼핑몰에서 쇼핑을 하면서 장바구니에 물건을 담는다고 생각해 보겠습니다.
만약 물건 하나를 담고 나서 한개의 물건을 담았다고 연결을 해제해버리면 두번째 상품의 데이터는 서버 입장에서 어떤 클라이언트가 담았는지 알 수가 없습니다.
데이터가 유지가 되어야 하는 상황에도 바로바로 해제되는 문제가 있다면 로그인을 하는 의미가 없어집니다.
로그아웃을 하거나 브라우저를 닫기전까지는 유지가 되어있어야 되기 때문이죠.
이러한 경우 쿠키라는 것을 이용할 수 있습니다.
클라이언트가 서버에 요청을하고 서버가 응답을 합니다.
이 과정에서 데이터를 서버에 저장하게되면 과부화가 걸릴수 있기 때문에 클라이언트에 저장을 하는 것입니다.
브라우저에 기존 연결정보를 저장하는 방식을 쿠키는 채택을 하였습니다.
클라이언트에 쿠키를 생성해서 연결정보를 저장하고 이렇게 남아있는 정보를 재연결할때 다시한번 사용하는 방법에 대해서 알아보고자 합니다.
실제 프로그래밍에서 쿠키를 구현하는 방법입니다.
어떤 클라이언트가 서버에 요청을 했습니다.
그럼 해당 쿠키가 null인지 먼저 확인을 하고 null이라면 새로운 쿠키를 생성하고 null이 아니라면 쿠키를 재활용합니다.
쿠키는 하나의 데이터만 관리하는 것이 아니라 여러개의 데이터를 관리할수도 있기 때문에 배열로 관리를 하게 됩니다.
또한 사용자정보의 데이터에 들어가기 때문에 request객체로부터 getCookies를 합니다.
쿠키들을 조회해서 쿠키중에 memberId라는 쿠키가 있으면 그것을 쿠키라는 객체에 담게되고 존재하지 않으면 새롭게 쿠키를 생성하게 됩니다.
이렇게 쿠키를 모두 재활용하거나 생성하게 되면 addCookie를 통해 응답하게 됩니다.
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<%
Cookie[] cookies = request.getCookies();
System.out.println("cookies : " + cookies);
if(cookies != null){
for(Cookie c : cookies){
if(c.getName().equals("memberId")){
response.sendRedirect("loginOk.jsp");
}
}
}
for(Cookie c : cookies){
out.print("name : " + c.getName() + "<br>");
out.print("value : " + c.getValue() + "<br>");
out.print("--------------------------------<br>");
}
%>
<form action="loginCon" method="post">
ID : <input type="text" name="mID"><br>
PW : <input type="password" name="mPW"><br>
<input type="submit" value="login">
</form>
</body>
</html>
package com.servlet;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* Servlet implementation class loginCon
*/
@WebServlet("/loginCon")
public class loginCon extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
PrintWriter out = response.getWriter();
String mId = request.getParameter("mID");
String mPw = request.getParameter("mPW");
out.print("mId : " + mId);
out.print("mPw : " + mPw);
Cookie[] cookies = request.getCookies();
Cookie cookie = null;
for(Cookie c : cookies) {
System.out.println("c.getName() : " + c.getName() + ", c.getValue() : " + c.getValue());
if(c.getName().equals("memberId")) {
cookie = c;
}
}
if(cookie == null) {
System.out.println("cookie is null");
cookie = new Cookie("memberId", mId);
}
response.addCookie(cookie);
cookie.setMaxAge(60 * 60);
response.sendRedirect("loginOk.jsp");
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
}
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<%
Cookie[] cookies = request.getCookies();
for(Cookie c : cookies){
out.print("name : " + c.getName() + "<br>");
out.print("value : " + c.getValue() + "<br>");
out.print("--------------------------------<br>");
}
%>
</body>
</html>
위의 그림에서 설명해드린 코드 로직을 구현해본 것입니다.
먼저 login.jsp에서
<%
Cookie[] cookies = request.getCookies();
System.out.println("cookies : " + cookies);
if(cookies != null){
for(Cookie c : cookies){
if(c.getName().equals("memberId")){
response.sendRedirect("loginOk.jsp");
}
}
}
for(Cookie c : cookies){
out.print("name : " + c.getName() + "<br>");
out.print("value : " + c.getValue() + "<br>");
out.print("--------------------------------<br>");
}
%>
해당 부분은 쿠키가 있는지 확인하고 쿠키가 있고 memberId와 같다면 loginOk.jsp로 전달해주고 어떤 쿠키가 들어있는지 로그를 찍어보는 코드입니다.
loginCon.java파일 즉 서블릿에서
cookie.setMaxAge(60 * 60);
해단 부분은 쿠키의 유지시간을 정해주는 것입니다.
60초의 60번이면 1시간이겠네요.
마지막으로 loginOk.jsp에서는 쿠키를 전달받아 출력시키주는 역할을 합니다.
<%
Cookie[] cookies = request.getCookies();
for(Cookie c : cookies){
out.print("name : " + c.getName() + "<br>");
out.print("value : " + c.getValue() + "<br>");
out.print("--------------------------------<br>");
}
%>
해당부분은 쿠키를 받아와서 쿠키를 전부다 찍어보는것이죠!
쿠키는 지금까지도 그렇고 앞으로도 많이 쓰이게될 중요한 기법인데 보안에 취약할수 있습니다.
사용자의 정보가 local(본인의 PC)에 저장이 되는데 정보 유출의 위험이 있기 때문이죠.
그래서 쿠키에 크리티컬한 이슈가 발생할 데이터를 저장하기 보다는 간단한 정보만 저장하고 서버에 데이터를 저장하는 session을 사용하는 것을 권장합니다.
이 글은 실전 JSP (renew ver.) - 신입 프로그래머를 위한 강좌를 수강하며 공부한 내용을 정리한 글입니다.
https://www.inflearn.com/course/실전-jsp_renew/dashboard
'Java 관련 > JSP & Servlet' 카테고리의 다른 글
[JSP & Servlet] JSP Servlet의 한글처리 (0) | 2022.08.21 |
---|---|
[JSP & Servlet] Session (1) | 2022.08.20 |
[JSP & Servlet] Servlet 데이터 공유 (0) | 2022.08.18 |
[JSP & Servlet] JSP 내장객체(config, application, out) (0) | 2022.08.17 |
[JSP & Servlet] request객체, response객체 (0) | 2022.08.16 |