web( jsp, servlet )/servlet

세션과 쿠키

읽히는 블로그 2024. 7. 15. 10:35

▤ 목차

     

     

     

    Authentication(인증) vs Authorization(인가)

    👏 한줄 정리

    인증은 로그인 과정과 같이 신원을 확인하는 과정을 말한다.

    인가는 로그인을 유지하여 어떠한 자원에 접근할 수 있는지 확인하는 절차를 말한다.

     

    • 인증은 유저, 장치의 신원을 증명하는 행위
    • 인가는 해당 유저, 장치에 접근 권한을 부여/거부 하는 행위
    • 인증은 인가로 이어진다
    • 인가는 인증으로 이어진다.
    • 토큰(인가)으로 신원을 파악하는 방법은 정확도가 떨어지는 방법이다.

     

     

    ✏️ 차이점

    서로 의미가 비슷하다고 생각할 수 있지만 다르다.

    인증을 통해 인가가 가능하지만 인가를 통해 인증을 확인할 수 없다.

    예를 들어 출입증이다.

     

    나의 신원으로 출입증을 받았다고 가정해보자.

    해당 출입증은 인증된 사용자가 사용하는 인가된 권한인 것이다.

    즉, 다른 사람이 해당 출입증을 빌려 출입을 할 수도 있다. 인가된 사용자라고 인증된 사용자라는 보장이 없는 것이다.

     

    인증된 사용자는 인가로 이어진다. 하지만 인가는 인증으로 이어지지 않는다. 인가는 개체를 식별하는데 사용할 수있는게 아니다.

     

     


     

     

    로그인만큼이나 상태를 유지하는 것도 기술이 필요한데, 이번에 정리할 것은 인가에 대한 내용이다.

     

    HTTP 통신은 TCP/IP 기반의 프로토콜이다.

    때문에 웹 사이트 내의 모든 요청과 응답은 Stateless한 특성을 가진다.

    클라이언트의 요청에 서버가 반응을 하고 연결을 끊어진다. 즉, 서버는 클라이언트의 상태를 기억하고 있지 않는다.

     

    인증을 받은 클라이언트의 상태를 기억하지 못하는 서버?

    로그인 해야 볼수있는 게시글들이 있다고 가정하자. 해당 글을 보기위해 로그인한 클라이언트가 다른 게시글을 클릭하면 다시 로그인 과정을 거쳐야하는 것이다. (볼때마다 로그인(인증)과정을 거쳐야한다.)

     

    이런 불상사를 막기 위해서 서버는 클라이언트에게 응답할때 "인증된 클라이언트이기에 인가해야한다"는 정보를 담아 보내기로 한다.

     

    위의 결과를 해결하기 위한 기술 구현은 크게 3가지로 설명할 수 있다.

    • 쿠키
    • 세션
    • JWT(Json Web Token)

     

    이번 글에서는 Cookie와 Session에 대해 정리하겠다.

     


     

    https://dongsik93.github.io/til/2020/01/08/til-authorization%281%29/

     

     

     

    ✔ 쿠키 ( Cookie )

    쿠키는 서버에서 사용자 브라우저로 전송하는 작은 데이터이다.

    개인적으로 부스러기처럼 약간의 정보를 클라이언트에게 같이 보내는 느낌으로 이해했다.

     

    F12 키를 눌러 자신의 쿠키를 확인할 수 있다.

     

     

    사용자가 화면을 통해 서버에게 특정 파일.. 등을 요구하는 경우, 서버는 해당 요청에 응답을 한다.

    이때, 응답시 단순히 응답 파일만 넘기는 것이아니라 해당 정보(로그인 상태 유지, 장바구니 유지, 검색 상품 광고 추천..)도 같이 사용자에게 넘기는 것이다.

    다음 요청이 들어올때 서버는 함께 넘긴 정보가 있는지 확인하는 것이다.

     

    • 사용자 인증 유효 시간을 명시할 수 있다.
    • 유효 시간이 정해지면 브라우저가 종료되어도 인증이 유지된다.
    • 서버가 클라이언트단에 저장해놓는 것이다. (클라이언트가 요청하지 않아도 브라우저가 요청시 header에 넣어서 전송된다.)
    • 300개까지 쿠키 저장이 가능하고 하나의 도메인당 쿠키는 20개의 값만 가질 수 있다. (FIFO 형식)
    • 하나의 쿠키값은 4KB까지 저장한다.
    • 브라우저마다 저장되는 쿠키는 다르다.(크롬으로 들어가는 것과 Edge로 들어가는 것 다른 사용자로 인식한다.)
    • 쿠키는 클라이언트단에서 삭제가 가능하기에 신뢰성이 낮다.

     

     

    🎯 사용 목적

    • 세션 관리 (Session Management) : 로그인, 사용자 닉네임, 접속 시간, 장바구니 등 서버가 알아야 할 정보들 저장
    • 개인화(Personalization) : 사용자마다 다르게 그 사람이 적절한 페이지를 보여줄 수 있다.
    • 트래킹(Tracking) : 사용자의 행동과 패턴을 분석하고 기록한다.

     

     

     

    👏 중요

    클라이언트의 요청을 할때 쿠키가 같이 서버로 넘어오는데, 이때 클라이언트는 자신의 모든 쿠키를 가지고 들어간다.

    즉, 서버는 자신이 찾는 쿠키를 for문을 통해 읽게된다.

    다르게 말하면 다른 서버에서 클라이언트의 쿠키를 읽을 수 있다는 의미이다.

    그래서 쿠키에는 중요한 정보를 담으면 안된다.

     

     

     

     

    💻 코드로 보기

    크롬에서 확인할 수 있는 쿠키 목록이다. 

     

    여기서 다른것보다 먼저 하고 싶은말은 , " 쿠키는 키와 값으로 구성되어 있다 "

     

    서블릿에서는 Cookie에 대한 클래스를 제공해준다.

     

     

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    		// 지정되지 않은 경우 먼저 실행되는 메서드
    		response.setContentType("text/html;charset=utf-8"); //mime type과 문자 코드
    		PrintWriter out = response.getWriter();
    		String id, addr;
    		
    		Cookie[] cookies = request.getCookies();
    		out.println("쿠키 이름 : "+cookies[0].getName());
    		out.println("쿠키 값 : "+cookies[0].getValue());
            
            //쿠키 유효 시간(절대적인 시간이아니다. 다시들어온 시점에서 다시 시작한다.)
            pwCoo.setMaxAge(10); //10초
    	}

     

     

    쿠키의 값은 인코딩된 값이다. 

    해당값을 알아볼 수 있도록 가져와보자.

     

     

    위에서 설명했듯, 클라이언트는 요청과 함께 모든 쿠키를 가지고 온다.

    따라서 서버는 필요한 쿠키를 for문을 통해서 찾는다.

     

    모든 쿠키를 가져온다.

     

     

     

     

     

    • 쿠키값은 중요한 정보를 담을 수 없다.
    • 쿠키는 클라이언트에 정보를 전달하기에 담을 수 있는 용도에 한계가 있다.
    • 쿠키는 사용자가 임의로 지울 수도 있고 수정할 수도 있기에 신뢰도가 낮다.

    위와 같은 단점들을 보완하기 위해서 세션이 등장하였다.

     

     

     

     

     

     


     

     

     

     

     

     

    세션 ( Session )

    세션은 쿠키에다 고객의 식별할 수 있는 ID를 만들어 넣어주는 방식이다. A 클라이언트가 처음 접속을 하면 서버는 해당 요청과 쿠키를 전달하는데, 이때 쿠키에 중요한 정보를 직접 담는 것이 아닌 세션 아이디 생성 후 쿠키에 저장한다.

    서버에서는 메모리를 확보한 후 고객의 주요 정보를 저장한다. (만약 외부 DB를 가지고 있으면 서버와 DB가 데이터 확인 겸 I/O가 발생한다.) 

    A 클라이언트가 다시 HTTP 요청을 할때 쿠키를 보내기때문에 서버는 세션 ID를 통해 클라이언트를 식별할 수 있는 것이다. 세션은 브라우저가 종료되기 전까지 클라이언트의 요청을 하나의 상태로 보고 그 상태를 유지할 수 있게 해주는 기술을 말한다.

     

    https://dev.gmarket.com/45

     

    • 웹 서버에 웹 컨테이너의 상태를 유지하기 위한 정보를 저장한다. (Stateful 하다. 상태 유지)
    • 각 클라이언트는 서로 다른 세션을 가진다. (고유성)
    • 세션의 유효시간을 지정할 수 있는데 일정 시간이 지나면 세션은 만료된다.
    • 서버 측에서 저장이 되기에 쿠키에 비해 신뢰도가 높다. (데이터 조작 방지 및 보안)
    • HTTP 프로토콜에 의존적이다. 왜냐하면 세션 ID는 쿠키를 통해 클라이언트에게 전송되기 때문이다.

     

     

     

    👏 종료 시점

    • 브라우저 종료시 세션 종료
    • 개발자가 정한 시점
    • 사용자가 서버에 최근에 요청한 시간을 기준으로 30분 정도 ( getLastAccessedTime() )

     

     

    ✒️ 코드로 보기

     

    @WebServlet("/sessionEx")
    public class sessionEx extends HttpServlet {
    	private static final long serialVersionUID = 1L;
           
    	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    		String name = request.getParameter("name");
    		String age = request.getParameter("age");
    		
    		HttpSession session = request.getSession(true); // 세션 읽어오기(true : 없으면 생성)
    		session.setMaxInactiveInterval(10); // 세션 유효시간 10초
    		
    		if (session != null) {
    			session.setAttribute("name", name);
    			session.setAttribute("id", age);
    		}
    		response.setContentType("text/html;charset=utf-8");
    		PrintWriter out = response.getWriter();
    		out.println("<html><body>");
    		out.println("Cookie session id : " + session.getId());
    		out.println ("<br>session id : " + session.getAttribute("id"));
    		out.println("<br>session 이용자 : " + session.getAttribute("name"));
    		out.println("</body></html>");
    	}
    }

     

     

     

     

     

     

     


     

     

    ✔ 쿠키와 세션

    👻 차이점

      쿠키 세션
    저장 위치 client server
    저장 형식 TEXT Object
    만료 시점 쿠키 저장 시 설정 정확한 시점을 알 수 없다.
    리소스 클라이언트 리소스 서버 리소스
    용량 제한 한 도메인당 20개, 한 쿠키당 4kb 제한 없다.
    속도 쿠키에 정보가 있기에 빠르다 서버에 있어서 속도가 느리다

     

     

    👌 장단점

      쿠키 세션
    장점 * 클라이언트 저장 :  서버에 부담을 줄여준다.

    *유연성 : 쿠키를 사용하여
    클라이언트의 상태를 유지할 수 있다.
    *서버 저장 : 보안이 강하고
    데이터 조작이 불가하다.

    *보안 : 세션ID만 쿠키로 전송되기에
    보안이 강하다.

    단점 * 보안 취약성 : 쿠키는 요청을 보낼때
    모든 쿠키를 전달한다. 때문에 보안에 취약하다.

    *크기 제한 : 각 도메인당 쿠키의
    총 크기에 제한이 있다.
    *서버 부하 : 세션은 서버 메모리를 확보하기에
    많은 세션 데이터가 저장되어 있으면
    서버 부하가 증가할 수 있다.

    *스케일링 : 세션을 유지하기 위해
    서버 감에 데이터를 동기화 해야할 수 있다.

     

     

     

     

    👏 중요

     

    처음 인증 절차를 거친 유저는 세션이 유효할때까지 로그인을 하지 않고 해당 서비스(댓글달기, 블로그, 카페 ..등)을 재인증 절차를 거치지 않고 인가를 해줘야한다.

     

    로그인을  브라우저에 저장해놓고 매번 로그인을 하는 방법은 어떤가?

    1. 클라이언트 입장에서 매번 로그인을 확인해야하기때문에 번거롭다.
    2. 서버 입장에서도 매번 들어온 값과 DB에서 값을 가지고와서 매칭하는 작업을 매 요청마다 반복하면 시간과 자원에 무리가 간다.

    DB에 바로 값을 저장시키면 안된다. 물론 쿠키에 담아서 가는것보다 세션을 이용해 서버에 저장하는 것이 보안상 좋지만

    DB가 뚫리면 그대로 고객의 정보가 유출되기 때문이다.

    이때 암호화해서 저장하는 방법이 있지 않을까? 

     

     

     

     


     

     

    😊정리

    세션을 사용한다는 것은 결국 쿠키와 세션을 같이 사용한다는 의미와 같다.

    쿠키 자체가 유의미한 값을 가지고 있지 않기에 보안상 안전하지만 세션 하이재킹 공격을 당할 우려가 있다.

    (HTTPS 를 사용하거나 세션의 유효시간을 넣어 해결이 가능하다.)

     

    세션 하이재킹(Session Hijacking)
    시스템에 접근할 적법한 사용자의 아이디와 패스워드를 모를 경우 공격 대상이 이미 시스템에 접속되어 세션이 연결되어 있는 상태를 가로채기 하는 공격

    https://nordvpn.com/ko/blog/session-hijacking-explained/
     

    세션 하이재킹이란? 어떻게 피할 수 있을까요? | NordVPN

    세션 하이재킹은 사용자의 지출 내역부터 비밀번호까지 수집하여 많은 피해를 입힐 수 있습니다. 이 글에서 세션 하이재킹의 뜻과 세션 하이재킹 방지 방법을 알아보세요.

    nordvpn.com