OAuth와 JWT
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 인증 과정 |
---|---|
1 | Request Token 요청, 발급 |
2 | 사용자 인증 페이지 호출 |
3 | 사용자 로그인 완료 |
4 | 사용자 권한 요청 및 수락 |
5 | Access Token 발급 |
6 | Access 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)
* 양 측(클라이언트, 서버)의 협의하에 사용되는 클레임
- 등록된 클레임 (registered)
- 인코딩 전 종합한 모습을 다음과 같이 볼 수 있습니다.
{
"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 |
---|---|
1 | User가 ID와 Password를 사용하여 로그인 시도 |
2 | 서버는 Request를 확인하고 Secret key를 통해 Access token 발급 |
3 | JWT를 Client에 전달 |
4 | Server는 JWT 서명(Signature)을 체크하고 내용(Payload)로부터 사용자 정보를 확인해 데이터 반환 |
5 | Client는 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의 상태를 저장하지 않는 성질에 대한 측면, 사용자의 편의, 보안성에서 굉장히 효율적이라는 생각을 했고 앞으로의 서비스들에서 사용하는 이유에 대해 명확하게 인지하고 사용할 수 있는 계기가 되었습니다.
📚 참고
- https://www.csoonline.com/article/3216404/what-is-oauth-how-the-open-authorization-framework-works.html
- https://d2.naver.com/helloworld/24942
- https://showerbugs.github.io/2017-11-16/OAuth-%EB%9E%80-%EB%AC%B4%EC%97%87%EC%9D%BC%EA%B9%8C
- https://gorokke.tistory.com/181
Author And Source
이 문제에 관하여(OAuth와 JWT), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://velog.io/@seo_kk/OAuth-Token저자 귀속: 원작자 정보가 원작자 URL에 포함되어 있으며 저작권은 원작자 소유입니다.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)