Skip to content

Latest commit

 

History

History
85 lines (79 loc) · 8.42 KB

로그인방식 쿠키와 세션 그리고 토큰방식(JWT).md

File metadata and controls

85 lines (79 loc) · 8.42 KB

로그인방식: 쿠키와 세션 그리고 토큰방식(JWT)

HTTP 프로토콜의 특징

  1. Connectionless
  • 클라이언트와 서버가 요청과 응답을 한 번 주고 받으면 연결을 끊어버리는 특성이 있다. 클라이언트가 request를 서버로 보내면 서버는 클라이언트가 보낸 request에 맞게 response를 보내고 연결을 끊는다.
  1. Stateless
  • 연결을 끊는 순간, 사용자와 서버의 통신이 끝나며 상태 정보는 유지하지 않는 특성이 있다. 브라우저를 닫을 때마다 로그인이 풀리지 않게, ‘상태’를 유지하는 방법은 1)쿠키와 세션 2)토큰기반 방식 이 있다.

쿠키와 세션

  • 쿠키
    • 클라이언트에 저장되는 키-값으로 구성된 작은 데이터 조각
    • 서버가 클라이언트에 정보를 전달할 때 저장하고자 하는 정보를 응답헤더(Cookie)에 저장하여 전달한다.
    • 쿠기에 담긴 데이터는 브라우저에서 관리됨(보통 만료 날짜를 서버에서 설정한다.)
    • 서버와 요청 응답으로 인해 쿠키가 저장되면 다음 요청은 쿠키에 담긴 정보를 이용해 참조한다.
    • 이름, 값, 만료 날짜 등으로 구성
    • 쿠키 동작 방식
      1. 클라이언트가 로그인 요청
      2. 서버에서 쿠키 생성 후 클라이언트로 전달
      3. 클라이언트가 서버로 요청을 보낼 때 쿠키 전송
      4. 쿠키를 이용해 유저 인증을 진행
    • 단점
      • 웹 브라우저 간 Cookie에 대한 지원 형태가 다르기 때문에 브라우저 간 공유가 불가능하다.
      • Cookie사이즈는 4kb로 제한되어있어 많은 양의 데이터를 담을 수 없다.
  • 세션
    • 쿠키를 기반으로 하지만 클라이언트에 저장하는 쿠키와 다르게 서버에 저장하여 관리→ 쿠키에 중요정보를 담지 않고, 인증을 위한 별개의 정보를 세션 저장소에 저장한다.
    • 서버에서는 클라이언트를 구별하기 위해 각각의 세션ID를 클라이언트 마다 부여하고, 클라이언트가 종료되기 전까지 유지한다.
      • 세션ID: 웹 서버 메모리에 저장되는 클라이언트에 대한 유니크한 ID(서버 또는 데이터 베이스에 저장)
    • 클라이언트에 저장하는 쿠키보다는 보안이 좋다.
    • 세션 동작 방식
      1. 클라이언트가 로그인 요청
      2. 서버는 클라이언트에게 고유한 세션 ID를 부여하고 세션 저장소에 저장한 후 클라이언트에게 발급한다.
      3. 클라이언트는 서버에서 발급받은 세션 ID를 쿠키에 저장하고, 요청을 보낼때 마다 쿠키를 보낸다.
      4. 서버는 쿠키에 담겨있는 세션 ID와 세션 저장소에 있는 정보를 대조한 후 데이터를 가져온다.
  • XSS(Cross Site Scripting): 쿠키는 클라이언트에서 자바 스크립트로 조회할 수 있기 때문에, 공격자들이 자바스크립트로 쿠키를 가로채고자 시도를 한다.
    • 해결 방법: HTTP Only Cookie 또는 secure cookie를 사용한다.
      • Set-Cookie: 쿠키명=쿠키값;path=/; secure
        • http프로토콜은 언제든지 패킷을 중간에 가로챌 수 있기 때문에 https 프로토콜을 사용하여 데이터를 암호화 해 통신한다. secure 설정을 하면 https프로토콜이 아닌 경우 쿠키를 전송하지 않게 된다.
      • Set-Cookie: 쿠키명=쿠키값;path=/; HttpOnly
        • 클라이언트에서 자바 스크립트로 쿠키를 조회할 수 있는데, 해당 옵션을 활성화하면 브라우저에서 쿠키에 접근할 수 없으므로 XSS와 같은 공격으로부터 안전하다.
    • 보통은 HTTP관련 라이브러리에 적혀있는 대로 axios.defaults.withCredentials=true;
  • 세션 하이재킹의 공격은 세션 유효시간으로 예방할 수 있다.
  • 세션-쿠키 방식의 단점: 로그인 할 때마다 세션 id를 저장해야하기 때문에, 로그인 중인 유저의 수가 늘어나면 서버의 메모리가 과부화 될 가능성이 있다.
    • 토큰 기반 인증 방식: JWT토큰->인증은 토큰 기반 인증 서버를 통해서 하게 하고, 서버는 stateless하게 내버려둔다.
  • 요청>토큰생성>이후 사용자가 토큰을 헤더(authorization 키에 넣어서 요청. 이 토큰을 기반으로)

JWT(JSON Web Token)

  • 헤더, 페이로드, 서명으로 이루어져 있으며 JSON객체로 인코딩된다. 메세지 인증, 암호화에 사용한다.
    • Header: 어떤 방법의 서명 알고리즘을 사용할 것인가에 대한 정보
    • Payload: 데이터, 토큰 발급자, 토큰 유효 기간(인증이 필요한 최소한의 정보만)
      • Header,Payload는 누구나 디코딩하여 내용을 확인할 수 있기 때문에, 유저의 비밀번호 같은 중요한 내용은 포함하지 않는다.
    • Signature: 헤더에 정의된 알고리즘으로 인코딩된 헤더와 페이로드를 합친 값, 그리고 비밀키를 기반으로 생성된 서명 값
      • Secret key를 알아야 signature를 복호화 할 수 있기 때문에, 토큰을 변조하였더라도 유효하지 않은 토큰은 검증이 가능하다.
  • 토큰 동작 방식
    1. 클라이언트가 로그인 요청을 한다.
    2. 서버에서 유저의 고유한 ID와 다른 인증 정보들을 payload에 담는다.
    3. JWT의 유효기간과 옵션을 설정한다.
    4. Secret Key를 이용해 토큰을 발급한다.
    5. 발급된 토큰은 클라이언트에 쿠키 또는 로컬 스토리지 등에 저장하여 요청을 보낼 때마다 같이 보낸다.
    6. 서버는 토큰을 Seceret Key로 복호화하여 검증하는 과정을 거친다.
    7. 검증이 완료되면 대응하는 데이터를 보내준다.
  • 장점
    1. 사용자가 인증되면 사용자는 모든 시스템에서 사용할 수 있는 보안 토큰을 받는다. 즉, 단일 엔드 포인트를 생성해서 다른 모든 서버 간의 API 상호 작용을 인증할 수 있다는 점에서 좋다.
    2. 사용자 인증에 필요한 모든 정보는 토큰 자체에 포함하기 때문에 별도의 인증 저장소가 필요없다. 세션의 경우는 계속해서 저장해야 함. 확장성, 디버깅, 사이즈가 작다. jwt토큰 자체가 독립적이다.
  • 단점:
    1. 더 많은 필드가 추가되면 토큰이 비대해져 트래픽에 영향을 준다.
    2. 탈취하여 디코딩하면 데이터를 볼 수 있다.
    3. 발급된 토큰은 삭제가 불가능하다. →Refresh Token
  • RefreshToken
    • Access Token만으로는 공격자가 요청하는 것인지 정상적인 클라이언트가 요청하는 것인지 알 수 없다. 그리고 Access Token은 언제든 탈취될 수 있다고 가정하기 때문에 중요 정보를 담아선 안된다. 따라서 AccessToken은 유효기간을 짧게 설정하고 Refresh Token의 유효기간은 길게 설정한다.
    • 동작방식
    • Access Token을 로컬스토리지 또는 세션스토리지에 저장하고, Refresh Token은 쿠키에 저장하고 보안 옵션(HTTP Only, Secure Cookie)들을 활성화한다. Refresh Token은 서버에도 저장되어 있어야 한다.
    • RefreshToken이 탈취될 경우
      1. RefreshToken만 탈취되면 공격자는 탈취한 토큰으로 계속 Access Toeken을 생성해서 정상적인 사용자처럼 서버에 계속 요청할 수 있다.
      2. 이를 방어하기 위해 추가 검증로직을 사용해야한다.
      3. DB에 사용자와 Access Token, Refresh Token들을 매핑하여 저장한다.
      4. 정상적인 유저의 Access Token이 만료된 경우 AccessToken과 RefreshToken을 서버로 보내서 새 AT을 요청한다.→서버에서는 DB에 저장된 AT,RT쌍과 클라이언트가 보낸 토큰 쌍을 비교한다.→ 일치하면 새 AT을 발급한다.
      5. 공격자가 RefreshToken을 탈취한 경우, 공격자가 탈취한 RT으로 새 AT 생성을 요청한다. →AT이 없이 요청하면 공격으로 간주한다. → 서버에서 AT와 RT를 폐기한다.
    • RefrestToken과 Access Token이 모두 탈취되면
      • 공격자는 정상적인 유저처럼 요청하고 새로운 AccessToken을 발급받게되어 대응할 방법이 없다!