Cookie, Session

star_pooh·2024년 12월 18일
0

TIL

목록 보기
36/39
post-thumbnail

인증과 인가

  • 인증(Authentication)
    • 사용자가 누구인지 확인하는 과정
      ex) 로그인
  • 인가(Authorization)
    • 사용자가 어떤 권한을 가지고 있는지 결정하는 과정
    • 인증 선행 필수
      ex) 회원만 조회 가능한 게시글, 본인이 작성한 게시글 수정

사용자의 웹 브라우저에 저장되는 정보로 사용자의 상태 혹은 세션을 유지하거나 사용자 경험을 개선하기 위해 사용. 사용자 세션 관리(로그인, 장바구니, 접속 시간), 광고 트래킹(사용자 행동)등이 포함됨.

  • 쿠키를 사용하는 이유
    • HTTP는 Stateless, Connectionless 특성을 가지고 있기 때문에 Client가 재요청시 Server는 이전 요청에 대한 정보를 기억하지 못함
    • 로그인과 같이 상태를 유지해야 하는 경우 발생
    • Request에 사용자 정보를 포함하면 해결
      • 로그인 후에는 사용자 정보와 관련된 값이 저장되어 있어야 함
    • 브라우저를 완전히 종료한 뒤 다시 열어도 사용자 정보가 유지되어야 함

💡 쿠키의 위치
브라우저 개발자 도구(F12) → Application → Cookies

  • 로그인 성공시 응답
    • Set-Cookie
    • 로그인시 전달된 ID, Password로 User 테이블 조회하여 일치여부 확인
    • 일치한다면 Set-Cookie를 활용해 Cookie에 사용할 값 저장
  • 로그인 이후 요청
    • 요청 헤더 Cookie : 사용자 정보
    • 로그인 이후의 모든 요청에는 Request Header에 항상 Cookie 값을 추가
      • 네트워크 트래픽이 추가적으로 발생
      • 최소한의 정보만 사용 해야 함
    • Cookie에 담겨있는 값으로 인증/인가를 진행

서버에서는 HTTP 응답 헤더에 Set-Cookie 속성을 사용해 생성하고 설정할 수 있음.

  • Cookie Header
    • Set-cookie
      • Server에서 Client로 Cookie 전달(Response Header)
    • Cookie
      • Client가 Cookie를 저장하고 HTTP 요청시 Server로 전달(Request Header)
// Response 알아보기
set-cookie: 
sessionId=abcd; 
expires=Sat, 11-Dec-2024 00:00:00 GMT;
path=/; 
domain=abcde.com;
Secure
  • Cookie의 생명주기
    • 세션 Cookie
      • 만료 날짜(expires, max-age)를 생략하면 브라우저 완전 종료시 까지만 유지(Default)
      • 브라우저를 완전 종료 후 다시 페이지를 방문했을 때 재로그인 필요
    • 영속 Cookie
      • 만료 날짜를 입력하면 해당 날짜까지 유지
        • expires=Sat, 11-Dec-2024 00:00:00 GMT; (해당 만료일이 되면 쿠키가 삭제됨)
        • max-age=3600 (초단위, 0이 되거나 음수를 지정하면 쿠기가 삭제됨)
  • Cookie의 도메인
    • 쿠키가 아무 사이트에서나 생기고 동작하면 안되기 때문에 설정
      • 필요없는 값 전송, 트래픽 문제 등이 발생
      • domain=abcde.com를 지정하여 쿠키를 저장
      • dev.abcde.com와 같은 서브 도메인에서도 쿠키에 접근
    • domain을 생략하면 현재 문서 기준 도메인만 적용
  • Cookie의 경로
    • 1차적으로 도메인으로 필터링 후 Path 적용
    • 일반적으로 path=/ 루트(전체)로 지정
    • 위 경로를 포함한 하위 경로 페이지만 쿠키에 접근
      • path=/api 지정
        • path=/api/example 가능
        • path=/example 불가능
  • Cookie 보안
    • Secure
      • 기본적으로 Cookie는 http, https 구분하지 않고 전송
      • Secure를 적용하면 https인 경우에만 전송
    • HttpOnly
      • XSS(Cross-site Scripting) 공격 방지
        • 악성 스크립트를 웹 페이지에 삽입하여 다른 사용자의 브라우저에서 실행되도록 하는 공격
      • 자바스크립트에서 Cookie 접근 불가
      • HTTP 요청시 사용
    • SameSite
      • 브라우저 지원 여부 확인필요
      • CSRF(Cross-Site Request Forgery) 공격 방지
        • 사용자가 의도하지 않은 상태에서 특정 요청을 서버에 전송하게 하여 사용자 계정에서 원치 않는 행동을 하게 만듦
      • 요청 도메인과 쿠키에 설정된 도메인이 같은 경우에만 쿠키 전송

Cookie의 문제점

  • 쿠키 값을 임의로 변경 가능
    • Client가 임의로 쿠키의 값을 변경하면 서버는 다른 유저로 인식
      • 브라우저 개발자도구(F12) → Application → Cookies → 값 수정 가능
  • Cookie에 저장된 Data는 탈취되기 쉬움
    • 네트워크 전송 구간에서 탈취될 확률 매우 높음
      • HTTPS를 사용하는 이유 중 하나
      • 민감한 정보를 저장하면 안됨
    • 한번 탈취된 정보는 변경이 없다면 반영구적으로 사용 가능
  • 대처 방법
    • 쿠키에 중요한값을 저장하지 않음
    • 일반 유저나 해커들이 알아보지 못하는 값을 노출
      • 일반적으로 암호화된 Token을 쿠키에 저장
      • 서버에서 암호화된 Token과 사용자를 매핑해서 인식
      • Token은 서버에서 관리
    • 토큰은 해커가 임의의 값을 넣어도 동작하지 않도록 만들어야 함
    • 토큰이 탈취 당해도 사용할 수 없도록 토큰 만료시간을 짧게 설정
    • 탈취가 의심되는 경우 해당 토큰을 강제로 만료시킴
      • 접속기기 혹은 IP가 다른 경우 등

Session

Session

Cookie를 사용한 방식은 여러가지 보안 문제가 있기 때문에 중요한 정보는 모두 서버에서 저장. Client와 서버는 예측 불가능한 임의의 값으로 연결.

  • Session 생성 순서
    • 로그인에 성공하면 Server에서 임의로 만든 Session ID를 생성
      • Session ID는 예측 불가능 해야 함(ex. UUID)
    • 생성된 Session ID와 조회한 User 인스턴스를 서버의 Session 저장소에 저장
      • 서버에 유저와 관련된 중요한 정보를 저장
  • Session 동작 순서
    • 로그인
      • 상태유지를 위해 Cookie 사용
        • 서버는 클라이언트에 Set-Cookie: SessionId=임의생성값 을 전달
        • 클라이언트는 Cookie 저장소에 전달받은 SessionId 값을 저장
    • 로그인 이후 요청
      • 클라이언트는 모든 요청에 Cookie의 SessionId를 전달
      • 서버에서는 전달된 SessionId로 Session 저장소를 조회
      • 로그인 시 저장하였던 Session 정보를 서버에서 사용
  • Session 특징
    • Session을 사용하여 서버에 민감한 정보를 저장
      • 예측이 불가능한 세션 ID를 사용하여 쿠키값을 변조해도 문제 없음
      • 세션 ID에 중요한 정보는 포함되어 있지 않음
      • 시간이 지나면 세션이 만료되도록 설정
      • 해킹이 의심되는 경우 해당 세션을 제거
    • 데이터를 저장하는 곳이 클라이언트가 아닌 서버라는 것이 쿠키와 다른 점
    • Servlet은 Session을 자체적으로 지원

Spring의 Session

  • @SessioinAttribute
    • 세션을 새로 생성하는 기능은 없음
    • 이미 로그인이 완료된 사용자를 찾는 경우, 즉 세션이 있는 경우에 사용
@Controller
@Requiredargsconstructor
public class SessionHomeController {
	private UserService userService;

	@GetMapping("/v2/session-home")
    public String homeV2(
            // 로그인 여부를 확인해야하므로 required = false
            @SessionAttribute(name = Const.LOGIN_USER, required = false) UserResponseDto loginUser,
            Model model) {
		// session에 loginUser가 없으면 Login 페이지로 이동
        if (loginUser == null) {
            return "session-login";
        }
        // Session이 정상적으로 조회되면 로그인된것으로 간주
        model.addAttribute("loginUser", loginUser);
        // home 화면으로 이동
        return "session-home";
    }
}
  • HttpSession
    • 세션을 간편하게 사용할 수 있도록 다양한 기능 지원
@Slf4j
@RestController
public class SessionController {
    @GetMapping("/session")
    public String session(HttpServletRequest request) {
        HttpSession session = request.getSession(false);

        if (session == null) {
            return "세션이 없습니다.";
        }

        // jsessionId 값 조회
        log.info("session.getId()={}", session.getId());
        // 세션의 유효 시간(초단위, 기본값은 1800)
        log.info("session.getMaxInactiveInterval()={}", session.getMaxInactiveInterval());
        // 세션 생성 시간
        log.info("session.getCreationTime()={}", session.getCreationTime());
        // 해당 세션에 마지막으로 접근한 시간
        log.info("session.getLastAccessedTime()={}", session.getLastAccessedTime());
        // 새로 생성된 세션인지 확인
        log.info("session.isNew()={}", session.isNew());
        return "세션 조회 성공!";
    }
}

Session TimeOut

Session은 logout 기능을 사용하여 session.invalidate(); 가 되어야 삭제되지만 대부분의 사용자들은 로그아웃을 굳이 하지않고, 브라우저를 종료함.

  • Session의 문제점
    • HTTP는 Connectionless 특성을 가지고 있어서 서버가 브라우저의 종료 여부 판별 불가
    • 서버에서 언제 세션을 삭제해야 하는지 판단 불가
    • JSESSIONID의 값을 탈취 당한 경우 해당 값으로 악의적인 요청 가능
    • 세션은 서버 메모리에 생성되고 자원은 한정적이기 때문에 꼭 필요한 경우만 생성 필요
  • Session 생명 주기
    • 기본적으로 30분을 기준으로 삭제
    • 실제 로그인 후 30분 이상의 시간동안 사용중인 사용자의 세션도 삭제됨
      • 재로그인 해야 하는 경우 발생
  • HttpSession 사용
    • 세션 생성 시점으로부터 30분이 아닌 서버에 최근 Session을 요청한 시간을 기준으로 30분 유지

Session의 한계

Session은 서버의 메모리를 사용하여 확장성이 제한됨.

  • 서버가 DB 혹은 메모리에 저장된 세션 정보를 매번 조회하여 오버헤드 발생
  • 서버가 상태를 유지해야 하므로 사용자 수가 많아질수록 부담 증가
  • Cookie는 웹 브라우저에만 존재하여 모바일 앱 등의 다양한 클라이언트에서 인증 처리 불가
  • Scale Out(수평적 확장)에서 서버간 세션 공유가 여려움

💡 오버헤드(Overhead)란?
어떤 처리를 하기 위해 들어가는 간접적인 처리 시간, 메모리 등을 의미한다.

0개의 댓글

관련 채용 정보