OAuth와 JWT

석호·2022년 2월 15일
1
post-thumbnail

OAuth 와 JWT

OAuth 와 JWT 의 차이점을 비교하는 사람들이 많지만, 사실 이는 잘못된 이야기입니다.
OAuth는 하나의 Framework이자 프로토콜(Protocol)이고 JWT는 토큰의 형식들 중 하나이니까요.

OAuth는 토큰을 요청하는 요청 및 응답의 순서와 형식을 가지고 있으며, JWT는 이러한 OAuth의 과정에서 발생하는 하나의 산물이라고 볼 수 있습니다.

그렇다면 OAuth는 무엇이고, JWT는 무엇이며 왜 사용할까요?

OAuth

❓OAuth

예전에는 개인정보를 여러 곳에 입력하면서 보안이 불안해지고, Application이 안전하다는 보장이 없었습니다.
이러한 문제를 보완하기위해서 Twitter는 2007년에 OAuth 1.0을 만들게 됩니다.

OAuth를 간략하게 설명해보자면, 간단하게 인증(Authentication)과 권한(Authorization)을 획득하는 행위로 볼 수 있습니다.

  • 인증 : 인증이란 시스템의 접근을 확인하는 것입니다. 로그인 같은 것이 이러한 행위라고 볼 수 있습니다.
  • 권한 : 권한의 권리를 검증하는 것입니다. HTTP의 특성 중 하나인, "상태를 저장하지 않는다"(stateless) 를 보완하기 위해 권리를 검증해야 합니다.

OAuth는 인터넷 사용자들이 비밀번호를 제공하지 않고 다른 웹사이트 상의 자신들의 정보에 대해 웹사이트나 애플리케이션의 접근 권한을 부여할 수 있는 공통적인 수단으로서 사용되는, 접근 위임을 위한 개방형 표준이다. (위키백과)

OAuth는 우리가 사용하는 환경에서도 많이 찾아볼 수 있습니다. (카카오톡 로그인, 구글 로그인 등)

OAuth를 이용해서 인증하는 과정을 OAuth Dance라고 하며, OAuth Dance를 다음과 같이 표현할 수 있습니다.

순서OAuth 인증 과정
1Request Token 요청, 발급
2사용자 인증 페이지 호출
3사용자 로그인 완료
4사용자 권한 요청 및 수락
5Access Token 발급
6Access Token을 이용해 서비스 정보 요청

이렇듯 OAuth는 Consumer (Oauth 인증을 사용해 Service Provider의 가능을 사용하려는 쪽)가 Service Provider (OAuth를 사용하는 Open API를 제공하는 서비스) 의 기능을 사용하기 위해 AccessToken을 발급받는 과정입니다.

OAuth를 사용하면 여러 서비스 제공자의 API를 신뢰할 수 있는 방법으로 사용할 수 있다는 것으로 해석해볼 수 있겠죠?

❓OAuth 1.0

처음 개발 되었던 OAuth 1.0은 문제를 가지고 있었습니다.

  • 절차가 복잡하여 구현이 복잡하다. (서비스 프로바이더에게 연산 부담이 발생한다.)
  • 웹이 아닌 Application의 지원이 부족하다.
  • HMAC을 통해 암호화를 하는 번거로운 과정을 겪는다. (HMAC란 해싱 기법을 적용하여 메시지의 위변조를 방지하는 기법)
  • 인증 토큰(Access token)이 만료되지 않는다.

그래서 이러한 단점들을 보완하기 위해 OAuth 2.0이 탄생하게 됩니다.

❓OAuth 2.0

그렇다면 OAuth 2.0은 어떻게 보완되어 탄생했을까요?

  • Siganature 단순화 정렬과 URL 인코딩이 필요 없도록 만들었다.
  • 웹 뿐만 아니라 Application에 지원을 강화했다.
  • 암호화가 필요 없다. HTTPS를 사용하며, HMAC를 사용하지 않는다.
  • 인증 토큰(Access token)에 Life-time을 지정할 수 있도록 했다.

이 외에도 OAuth 2.0에서 사용하는 용어 체계는 OAuth 1.0과 완전히 다르다고 합니다.
목적만 같고 다른 프로토콜이라고 볼 수 있는 것이죠.

이제 OAuth 과정에서 생성되는 Token의 종류 중 하나이며 가장 자주 사용되는 JWT에 대해서 정리해보겠습니다.

JWT

❓Token 기반 인증

HTTP 방식의 통신에서 쿠키나 세션을 이용한 인증보다 보안성이 강하며 효율적이라고 평가받는 인증은 바로 토큰 기반 인증입니다.
토큰 기반 인증은 사용자가 자신의 아이덴티티를 확인한 뒤 고유한 Access토큰을 받을 수 있는 프로토콜을 말합니다.
JWT는 토큰 기반 인증 프로토콜에서 가장 대표적인 토큰입니다.

❓JWT

Json Web Token의 약자로 전자 서명 된 URL-safe(URL로 이용할 수 있는 문자로만 구성된 것인데, URL에서 파라미터로 사용할 수 있도록 하기 위함)의 JSON 입니다.
JWT는 자가수용적(self-contained)이라는 특징을 가지고 있는데, 이는 JWT가 필요한 모든 정보를 자체적으로 가지고 있다는 것을 뜻합니다.
JWT 토큰은 3가지 구조로 나뉘어 있습니다.

  • 헤더(header)

    • 토큰의 타입정보가 들어가있습니다.
    • 해시 알고리즘 정보가 들어가있습니다.
    • 헤더의 내용은 BASE64 방식으로 인코딩해서 기록됩니다.
    • 헤더를 디코딩 한 모습을 다음과 같이 볼 수 있습니다.
{
  "typ": "JWT",
  "alg": "HS256"
}
  • 내용(payload)

    • 토큰에 담을 정보가 들어가 있으며, 이 정보의 한 조각을 클레임이라 부릅니다.
    • 총 3가지 클레임을 조합하여 BASE64 인코딩된 정보입니다.
      • 등록된 클레임 (registered)
        * 토큰 발급자(iss), 토큰 제목(sub), 토큰 대상자(aud), 토큰의 만료시간(exp)
      • 공개 클레임 (public)
        * 충돌을 방지하기 위한 URI 형식의 이름
      • 비공개 클레임 (private)
        * 양 측(클라이언트, 서버)의 협의하에 사용되는 클레임
    • 인코딩 전 종합한 모습을 다음과 같이 볼 수 있습니다.
{
  "iss": "seo_kk.com",		// 등록된 클레임
  "exp": "1485270000000", 	// 등록된 클레임
  "https://seo_kk.com/jwt_claims/is_admin": true,	// 공개 클레임
  "userId": "11028373727102",	// 비공개 클레임
  "username": "seo_kk"		// 비공개 클레임
}
  • 서명(signature)

    • JWT가 원본 그대로라는 것을 확인할 때 사용합니다.
    • 토큰을 인코딩하거나 유효성 검증을 할 때 사용하는 고유한 암호코드입니다.
    • 별도생성된 JWT secret을 헤더에 지정된 암호 알고리즘으로 암호화한 것입니다.
    • 헤더(base64인코딩) + 페이로드(base64인코딩) + SECRET_KEY 를 사용하여 JWT를 발급하는 백엔드 서버에서 발행됩니다.

생성된 JWT는 이러합니다.

이렇게 생성된 JWT는 다음과 같은 Process를 가집니다.

JWT Process

순서JWT Process
1User가 ID와 Password를 사용하여 로그인 시도
2서버는 Request를 확인하고 Secret key를 통해 Access token 발급
3JWT를 Client에 전달
4Server는 JWT 서명(Signature)을 체크하고 내용(Payload)로부터 사용자 정보를 확인해 데이터 반환
5Client는 JWT를 사용하여 API를 제공받는다.

그림으로 표현하면 다음과 같이 볼 수 있습니다.

이렇게 JWT의 Process를 알아 보았습니다.

세션기반 인증, 쿠키기반 인증보다 효율적이라고 하지만 분명히 장단점은 존재하겠죠?
JWT의 장단점에는 무엇이 있을까요?

JWT의 장점

  • JWT는 사용자 인증에 필요한 모든 정보를 토큰에 포함하기 때문에 별도의 인증 저장소가 필요합니다.
  • 쿠키를 사용하지 않아도 되기에 쿠키 사용으로 인한 취약점이 해결됩니다.
  • URL 파라미터와 헤더로 사용하기에 편리합니다.
  • 트래픽에 대한 부담이 낮습니다.
  • REST 서비스로 제공 가능합니다.
  • 만료기한이 내장되어 있습니다.

JWT의 단점

  • JWT는 토큰 자체에 사용자 인증에 필요한 정보를 담고 있기 때문에 정보를 완전히 차단하고 있다고는 어렵습니다.
  • 정보를 담는 Payload에 정보가 많아질수록 토큰의 길이가 늘어나 네트워크에 부하를 줄 수 있습니다.
  • Payload 자체는 암호화된것이 아니라 BASE64로 인코딩 된것이기에, JWE로 암호화 하거나 중요 데이터를 Payload에 넣으면 안됩니다. 중간 탈취자가 디코딩할수도 있기 때문이죠.
  • JWT는 stateless(상태를 저장하지 않는다)이기 때문에, 토큰을 임의로 삭제하는 것이 불가능합니다. 그렇기에 토큰 만료시간을 꼭 넣어주어야 합니다.
  • 토큰을 Client 측에서 저장해야 합니다.

정리

OAuth와 JWT는 많은 Application에서 사용하고 있다고 알고 있습니다.
저도 개발을 진행하면서 JWT를 사용하고, OAuth를 자주 사용했습니다.
하지만 "왜 사용하는지, 어떻게 동작하는지" 에 대해서는 정확히 인지하지 못하고 사용했습니다.
자료들을 찾아보면서 HTTP의 상태를 저장하지 않는 성질에 대한 측면, 사용자의 편의, 보안성에서 굉장히 효율적이라는 생각을 했고 앞으로의 서비스들에서 사용하는 이유에 대해 명확하게 인지하고 사용할 수 있는 계기가 되었습니다.


📚 참고

profile
BackEnd Developer

0개의 댓글