본문 바로가기
내일배움캠프(Sparta)/Spring

[Spring] Authentication / Authorization / Cookie / Session

by mmm- 2023. 11. 8.

1) Authentication & Authorization 

Authentication (인증)

 : 해당 유저가 실제 그 유저가 맞는지 확인하는 절차
(ex; 지문인식, 로그인 ..)

 

Authorization (인가)

: 해당 유저가 특정 리소스에 접근이 가능한지 허가를 확인하는 개념
(ex; 관리페이지 - 관리자 권한, 회원/비회원)


웹 애플리케이션 인증의 특수성

  1. 일반적으로 서버-클라이언트 구조로 되어있고, 실제로 이 서버-클라이언트는 아주 멀리 떨어져 있음
  2.  서버의 비용 및 부담을 줄이기 위해 HTTP 프로토콜을 이용해 비연결성(Connectionless)무상태(Stateless)로 이루어진 통신을 함

비연결성, 무상태 프로토콜에서 유저 인증에 대한 정보를 어떻게 유지하는 것일까?

 

인증 방식

1. 쿠키-세션 방식의 인증

: 서버가 '특정 유저가 로그인 되었다'는 상태를 저장하는 방식 

  • 인증과 관련된 최소한의 정보만 저장해 로그인을 유지시킴.

  1. 사용자가 로그인 진행
  2. 서버는 DB의 유저 테이블에서 아이디, 비밀번호를 찾아 대조
  3. 정보와 일치하면 세션 저장소에 해당 유저가 로그인 상태라는 정보 넣음
  4. 세션 저장소에서 유저 정보와 관련없는 난수인 session-id 발급
  5. 서버는 로그인 요청에 대한 응답으로 session-id 지급
  6. 클라이언트는 받은 session-id를 쿠키에 보관하고, 요청을 할 때마다 세션 아이디 같이보냄
    (주로 HTTP header에 담아서)
  7.  서버는 클라이언트 요청에서 쿠키를 발견하면 세션 저장소에서 쿠키 검증
  8. 유저정보를 받아와 해당 사용자가 로그인되어 있는 사용자라면 그에 따른 응답

 

2. JWT(JSON Web Token) 기반 인증

: 인증에 필요한 정보들을 암호화시킨 토큰

  • JWT(Access Token)를 HTTP 헤더에 실어 서버가 클라이언트 식별

  1. 사용자가 로그인 진행
  2. 서버는 DB의 유저 테이블에서 아이디, 비밀번호를 찾아 대조
  3. 정보가 일치하면 유저정보를 JWT로 암호화해 내보냄
  4. 서버는 로그인 요청에 대한 응답으로 JWT 토큰 전달
  5. 클라이언트는 받은 토큰을 저장소에 보관해 앞으로의 요청마다 토큰을 같이 보냄
  6. 서버는 요청에서 토큰을 발견하면 토큰을 검증
  7. 이후에는 로그인 된 유저에 따른 응답

 

쿠키-세션 방식에서 검증할 때 비교를 위해 존재했던 세션 저장소가 JWT에서는 없음

그래서 JWT는 따로 저장할 필요가 없기 때문에 더 효율적일 수 있음.


2) 쿠키와 세션

➡️ HTTP에 상태 정보를 유지(Stateful)하기 위해 사용
(쿠키와 세션을 통해 서버에서는 클라이언트 별로 인증 및 인가 가능)

 

1. 쿠키

: 클라이언트에 저장될 목적으로 생성한 작은 정보를 담은 파일

구성요소

  • Name (이름): 쿠키를 구별하는 데 사용되는 키 (중복 불가)
  • Value (값): 쿠키의 값
  • Domain (도메인): 쿠키가 저장된 도메인
  • Path (경로): 쿠키가 사용되는 경로
  • Expires (만료기한): 쿠키 만료기한(만료시한 지나면 삭제됨)

 

2. 세션

: 서버에서 일정시간동안 클라이언트 상태를 유지하기 위해 사용

  • 서버에서 클라이언트 별로 '세션 ID'를 부여한 후 클라이언트 별 필요한 정보를 서버에 저장
  • 서버에서 생성한 '세션 ID'는 클라이언트의 쿠키값(세션쿠)으로 저장되어 클라이언트 식별에 사용
  • 실제로는 연결된 것이 아니지만 세션을 통해 연결되는 것처럼 보여줄 수 있음.

동작방식

 

 

 

 

 

1. 클라이언트가 서버에 1번째 요청

2. 서버가 세션ID 생성 후 쿠키에 담아 응답 헤더에 전달

3. 클라이언트가 쿠키에 세션 ID 저장 (세션쿠키)

4. 클라이언트 서버에 2번째 요청을 보낼 때 해당하는 쿠키값(세션 ID) 포함해서 보냄

5. 서버가 세션ID를 확인하고 1번 요청과 같은 클라이언트임을 인지

 

 

 

 

➡️ 이어지는 것처럼 보이기 위해 세션 ID를 응답할 때 주고, 클라이언트도 응답할 때 같이 보내주면 서버에서 검증해서 연결되어있는 것처럼 유지.

 

 

3. 쿠키 vs 세션

  쿠키 (Cookie) 세션 (Session)
설명 클라이언트에 저장될 목적으로 생성한 작은 정보를 담은 파일 서버에서 일정시간동안 클라이언트 상태를 유지하기 위해 사용
저장위치 클라이언트 (웹 브라우저) 웹 서버
사용 예 사이트 팝업의 "오늘 다시보지 않기" 정보 저장 로그인 정보 저장
만료 시점 쿠키 저장시 만료일시 설정 가능 
(브라우저 종료시도 유지 가능)
다음 조건 중 하나가 만족될 경우 만료됨
1. 브라우저 종료시
2. 클라이언트 로그아웃시
3. 서버에 설정한 유지기간까지 해당 클라이언트의 재요청이 없는 경우
용량 제한 브라우저 별로 다름 (크롬 기준)
- 하나의 도메인 당 180개
- 하나의 쿠키 당 4KB(=4096byte)
개수 제한 없음
(단, 세션 저장소 크기 이상 저장 불가능)
보안 취약
(클라이언트에서 쿠키 정보를 쉽게 변경, 삭제 및 가로채기 당할 수 있음)
비교적 안전
(서버에 저장되기 때문에 상대적으로 안전)

4. 쿠키 다루기

쿠키 생성

  • Cookie Value에는 공백이 불가능해 encoding을 해줘야 함.
  • new Cookie(AUTHORIZATION_HEADER, cookieValue);
    • Cookie에 저장될 Name과 Value를 생성자로 받는 Cookie 객체 생성
  • SetPath("/"), setMaxAge(30 * 60)
    • Path 와 만료시간 지정
  • HttpServletResponse 객체에 생성한 Cookie 객체를 추가해 브라우저로 반환하면 반환된 Cookie는 브라우저의 쿠키 저장소에 저장
  • Cookie 생성은 범용적으로 사용될 수 있기 때문에 static 메서드로 선언

 

쿠키 읽기

  • @CookieValue("Cookie의 Name")
    • Cookie의 Name 정보를 전달해주면 해당 정보를 토대로 Cookie의 Value를 가져옴

5. 세션 다루기

  • Servlet에서는 세션ID를 간편하게 만들 수 있는 HttpSession을 제공해줌.

HttpSession 생성

  • HttpServletRequest를 사용해 세션을 생성 및 반환할 수 있음
  • req.getSession(true)
    • 세션이 존재할 경우 세션을 반환하고 없을 경우 새로운 세션 생성
  • 세션에 저장할 정보를 Name-Value 형식으로 추가
  • 반환된 세션은 브라우저 Cookie 저장소에 JSESSIONID라는 Name으로 Value에 저장됨

 

HttpSession 읽기

  • req.getSession(false)
    • 세션이 존재할 경우 세션을, 없을 경우 null 반환
  • session.getAttribute("세션에 저장된 정보 Name")
    • Name을 사용하여 세션에 저장된 Value를 가져옴

 

용어 정리

  • 비연결성(Connectionless)
    : 서버와 클라이언트가 항상 연결 상태를 유지하지 않은 특성
    • 리소스를 절약하기 위해 서버는 클라이언트의 요청에 대한 응답을 완료하면 즉시 연결을 끊어버림.
  • 무상태(Stateless)
    : 서버가 클라이언트의 상태를 저장하지 않는다는 것
    • 서버의 비용과 부담을 증가시키는 것을 막기 위해 기존의 상태가 없다고 가정하는 프로토콜로 구현되어 있어 서버는 클라이언트가 전에 어떤 요청을 보냈는지 알지 못함.

'내일배움캠프(Sparta) > Spring' 카테고리의 다른 글

[Spring] Filter  (0) 2023.11.09
[Spring] JWT / 패스워드 암호화  (0) 2023.11.08
[Spring] Bean  (0) 2023.11.08
[Spring] Spring Data JPA / JPA Auditing / Query Methods  (0) 2023.11.07
[Spring] SpringBoot의 JPA  (0) 2023.11.07