JWT (Token)

Kim Yongbin·2022년 10월 5일
0

GDSC

목록 보기
3/6

세션 기반 인증 VS 토큰 기반 인증

세션 기반 인증

HTTP는 무상태성(stateless) 프로토콜이기 때문에, 누가 요청했고, 누가 인증된 클라이언트인지 알 수 없다. 따라서 서버에 클라이언트의 접속 상태를 저장하는 것이 세션 기반 인증이다.

서버는 세션 storage에 클라이언트는 주로 쿠키에 세션 값을 저장한다. 클라이언트에서 요청이 들어오면 세션 storage에서 확인하여 유효한 세션인지 확인한다.

토큰 기반 인증

사용자의 인증 정보를 토큰에 담아 서버로 전달한다. 서버는 토큰에 담긴 사용자 정보를 따로 저장하지 않고 바로 검증한다. 사용자 인증이 된다면 클라이언트에 공개/개인 키를 이용해 서명한 토큰을 클라이언트에 전달한다.

클라이언트는 데이터 요청을 할 때 해당 토큰을 주로 헤더에 담아 요청을 날린다. 서버는 이 토큰이 유효한지 확인 후 반응을 보낸다.

세션 vs 토큰

  • 사용자 정보
    • 세션: 포함
    • 토큰: 미포함
  • 상태 정보
    • 세션: 서버에 저장 O
    • 토큰: 서버에 저장 X

JWT (JSON Web Token)

인증에 필요한 정보를 토큰에 담아 암호화 시켜 사용한다. 데이터들은 JSON의 형태로 작성되며, 비밀키 또는 공개/개인 키로 서명하여 사용한다. 공개/개인 키를 사용함을써 송신자를 특정할 수 있고, 데이터의 무결성도 확인할 수 있다.

JWT 구조

  • Header

    → 토큰의 타입과 서명에 사용된 알고리즘을 명시한다.

    {
    	"typ": "JWT",
    	"alg": "HS256"
    }
    • typ: 토큰의 타입을 명시
    • alg: 서명 알고리즘 명시
  • Payload

    → 토큰에 대한 property를 key-value로 저장하며, 이 데이터 하나하나를 claim이라고 한다.

    {
    	"sub": "1",
    	"iss": "ori",
    	"exp": 1636989718,
    	"iat": 1636989718,
    }
    • Registerd claims: 토큰에 관한 정보를 담기 위해 이미 등록된 클레임
    • Public claims: 사용자가 정의할 수 있는 클레임
    • Private claims: 토큰 사용자간 정보 공유를 위해 만들어 사용하는 클레임
주의: payload에는 민감한 정보를 담지 않는다.
  • Signature → 헤더와 페이로드를 서명한 값.
    HMACSHA256(
    	base64UrlEncode(header) + "." + 
    	base64UrlEncode(payload),
    	secretkey
    )
    • 시크릿 키를 이용해 base64 url로 인코딩한 헤더와 페이로드를 규정된 해싱 할고리즘으로 서명한다.
    • 서버는 이 서명과 전달된 헤더, 페이로드를 이용하여 유효한 토큰인지 검사한다. → 서버가 가지고 있는 개인키를 가지고 Signature를 복호화하여 비교한다.

장점

  • 토큰 자체가 인증된 정보이기 때문에 별도의 인증서 저장소가 필수가 아니다.
  • 클라이언트의 상태를 서버에서 저장하지 않아도 된다.
  • Signature를 공통/개인 키 암호화를 통해 막아 보완성이 증가했다.

취약점

  • 정보노출
    • JWT의 페이로드의 데이터는 암호화되지 않고 base64로 인코딩한 값이다. 이 값은 누구나 디코딩하여 확인할 수 있으므로 민감한 정보를 담지 않는다.
  • None algorithm
    • JWT의 알고리즘 타입 중 none이 있는데, 이 알고리즘은 서명 값 검증을 하지 않는다.

    • none 알고리즘을 허용할 경우 악의적 사용자가 서명 없이 토큰을 생성해 인증 절차를 우회하여 데이터에 접근 할 수 있다.

      → 이 위험을 줄이기 위해 none 알고리즘을 이용한 서명 없는 토큰은 사용할 수 없게 막아야 한다.

  • 서명 키 값 노출
    • 서명 키 값을 획득한다면 페이로드의 데이터를 변조하여 유효한 토큰을 생성할 수 있다.

    • 이를 이용해 악의적 행위가 가능하다.

      → 이 위험을 줄이기 위해 복잡도가 높은 비밀키를 사용해 토큰을 암호화하여야 한다.

  • 토큰 유효기간 및 파기
    • 토큰의 서명을 이용해 검증하면 토큰의 만료 시점까지 사용이 가능하다. 토큰이 중간에 탈취될 경우 만료될 때까지 악의적으로 사용될 위험이 있다.

      → 이 위험을 줄이기 위해 Access 토큰과 Refresh 토큰을 사용한다.

Reference

https://blog.lgcns.com/2687

https://ko.wikipedia.org/wiki/JSON토큰

profile
반박 시 여러분의 말이 맞습니다.

0개의 댓글