[SPRING] 서버 인증 방식(세션/쿠키, 토큰)

라미·2024년 2월 27일
0

spring

목록 보기
14/17
post-thumbnail

인증과 인가

인증(Authentication)
해당 유저가 실제 유저인지 인증 하는 개념
실제 그 유저가 맞는지 확인하는 절차
ex) 스마트폰 지문인식, 사이트 로그인 등

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

웹에서의 인증과 인가 처리

저번 HTTP 에 관해 알아 봤을 때와 같이 HTTP 통신은 HTTP 비연결성(Connectionless) 무상태(Stateless) 이기 때문에 1개의 요청에 1개의 응답만 있고 서버는 클라이언트의 상태를 저장하지 않는다.

쿠키-세션 방식의 인증

쿠키-세션 방식은 서버가 ‘특정 유저가 로그인 되었다’는 상태를 저장하는 방식.
인증과 관련된 최소한의 정보만 저장해서 로그인을 유지시킨다

쿠키는 서버와 클라이언트가 대화하기 위한 수단의 일종

  • 브라우저가 서버와 연결이 되었을 때 브라우저에서 자동적으로 쿠키를 생성하고, response 할 때 쿠키를 담아서 보낸다.
  • 특정 호스트에서 생성된 쿠키는 이후 모든 요청마다 서버로 전송됨
  • 요청 해더의 set-cookie 속성에 정보를 담을 수 있음.
  • 쿠키에 담긴 데이터는 브라우저에서 관리됨.
  • 이름(Name), 값(value), 도메인(Domain), 경로(Path), 만료 기한(Expires) 정보로 구성.
    개발자도구 - Application - Storage - Cookies 도메인 별로 저장

Session (인증정보)

서버와 클라이언트의 연결이 활성화된 상태

  • 클라이언트가 서버와 통신을 시작하면 서버는 해당 클라이언트에 대해 유일한 값인 세션 id를 부여, 세션 스토리지에 세션 정보를 저장함.
  • 클라이언트는 이 세션id를 쿠키를 통해 기억함.
  • 이후 클라이언트가 어떤 요청을 보낼 때마다 헤더의 cookie에 세션 id를 담아서 전송함.
  • 서버는 클라이언트가 보낸 요청의 쿠키에 담긴 세션 id와 세션 스토리지에 담긴 세션 id를 대조해 인증 상태를 판단함.
    (즉, 세션과 쿠키는 완전히 분리된 개념이 아니며 세션은 쿠키를 기반으로 함)
  • 각 클라이언트마다 유니크한 세션 객체가 주어지고, 이 세션 객체에 데이터를 담아 관리할 수 도 있음.
    (세션 객체가 자물쇠로 잠긴 상자라면 세션 id 가 열쇠인 셈)
  • 세션을 사용하지 않고 쿠키만으로 어떤 데이터를 주고받는다면, 클라이언트는 이미 모든 데이터를 알고 있다는 것.
  1. 사용자 로그인
  2. 사용자 확인
  3. 유저가 맞다면 세션 저장소에 해당 유저가 로그인 되었다는 정보를 넣는다
  4. 세션 저장소에서 유저의 정보와 관련 없는 난수인 session ID 발급
    (유저와 관련있으면 보안에 좋지 x)
  5. 서버는 발급된 session ID 응답에 담아서 보내준다
  6. 브라우저(클라이언트)에서 쿠키에 session ID를 저장, 요청마다 세션 아이디를 같이 보낸다.
    (주로 HTTP header에 담아서 보낸다)
  7. 클라이언트의 요청에서 쿠키가 있다면 세션저장소에서 쿠키 검증
  8. 유저 정보를 받아왔다면 로그인 된 사용자!
  9. 로그인 된 유저에 따른 응답을 보낸다

JWT 기반 인증

JWT : JSON Web Token
인증에 필요한 정보를 암호화 시킨다,
JWT를 HTTP header에 실어서 서버가 클라이언트를 식별 할 수 있도록 한다.

JWT

JSON Web Token의 약자로 JSON 포맷을 이용하여 사용자에 대한 속성을 저장하는 Claim 기반의 Web Token.
토큰의 한 종류, 쿠키 저장소를 사용하여 JWT를 저장한다.

JWT 사용이유
로그인 정보를 Server 에 저장하지 않고, Client 에 로그인 정보를 JWT 로 암호화하여 저장 → JWT 통해 인증/인가

  • 모든 서버에서 동일한 Secret key를 소유한다.

🔑 Secret Key의 사용

🪙 JWT 구조
JWT 는 누구나 평문으로 복호화 가능하지만 Secret key가 없으면 JWT 수정이 불가능하다.
Header : 암호화 방식(alg), 타입(type) 등
Payload : 서버에서 보낼 데이터. 일반적으로 유저의 고유 ID값, 유효기간(실제 유저정보 들어있다)
Verify Signature : Base64 방식으로 인코딩한 Header,payload 그리고 SECRET KEY를 더한 후 서명

  1. 사용자가 로그인을 한다.
  2. 서버는 DB 정보와 비교하여 사용자 확인을 한다.
  3. 유저가 맞다면 유저의 정보를 JWT로 암호화 하여 보낸다
  4. 서버는 로그인 요청의 응답으로 JWT Acess Token을 내보내준다
    (주로 HTTP header에 담아서 보낸다)
  5. 클라이언트는 그 토큰을 저장소에 보관하고 앞으로의 요청마다 토큰을 같이 보낸다.
  6. 클라이언트의 요청에서 토큰을 발견했다면 서버는 토큰을 검증한다.
  7. 로그인 된 유저에 따른 응답을 보낸다

세션/쿠키 방식과 가장 큰 차이점은 세션/쿠키는 세션 저장소에 유저의 정보를 넣는 반면, JWT는 토큰안에 유저의 정보들을 넣는다는 점이다. 클라이언트 입장에서는 HTTP 헤더에 세션ID나 토큰을 실어서 보내준다는 점에서는 동일하나, 서버측에서는 인증을 위해 암호화를 하냐 별도의 저장소를 이용하냐의 차이가 발생한다.

JWT 장/단점

JWT 장점

동시 접속자가 많을 때 서버 측 부하 낮춤
Client, Server가 다른 도메인을 사용할때

JWT 단점

구현의 복잡도 증가
JWT에 담는 내용이 커질 수록 네트워크 비용 증가 (클라이언트 → 서버)
이미 생성된 JWT를 일부만 만료시킬 방법이 없음
Secret key 유출 시 JWT 조작 가능

JWT 사용 흐름

  1. 로그인 성공
    1. 서버에서 "로그인 정보" → JWT 로 암호화 (Secret Key 사용)
    2. 서버에서 직접 쿠키를 생성해 JWT를 담아 Client 응답에 전달(전달 방법은 개발자가 정함 주로 Header에 전달)
    3. 브라우저 쿠키 저장소에 자동으로 JWT 저장됨
  2. Client 에서 JWT 통해 인증방법
    1. 서버에서 API 요청 시마다 쿠키에 포함된 JWT를 찾아서 사용
      (쿠키에 담긴 정보가 여러 개일 수 있기 때문에 그 중 이름이 JWT가 담긴 쿠키의 이름과 동일한지 확인하여 JWT를 가져온다)
    2. Server
      1. Client 가 전달한 JWT 위조 여부 검증 (Secret Key 사용)
      2. JWT 유효기간이 지나지 않았는지 검증
      3. 검증 성공시 JWT에서 사용자 정보를 가져와 확인

0개의 댓글