개발모음집

Token, JWT, OAuth 본문

Theory

Token, JWT, OAuth

void 2020. 3. 28. 10:00

JSON Web Token




* Token

프로그래밍 언어에서의 토큰은, 문법적으로 더 이상 나눌 수 없는 기본적인 언어요소를 말하는데, 예를 들어 하나의 키워드나 연산자 또는 구두점 등이 토큰이 될수 있다.

 

토큰 기반 시스템의 작동 원리

토큰 기반 시스템은 stateless 합니다. 무상태. 즉 상태유지를 하지 않는다는 것이죠. 이 시스템에서는 더 이상 유저의 인증 정보를 서버나 세션에 담아두지 않습니다. 이 개념 하나만으로도 위에서 서술한 서버에서 유저의 인증 정보를 서버측에 담아둠으로서 발생하는 많은 문제점들이 해소됩니다.

세션이 존재하지 않으니, 유저들이 로그인 되어있는지 안되어있는지 신경도 쓰지 않으면서 서버를 손쉽게 확장 할 수 있겠죠?

토큰 기반 시스템의 구현 방식은 시스템마다 크고작은 차이가 있겠지만, 대략적으로 보면 다음과 같습니다:

  1. 유저가 아이디와 비밀번호로 로그인을 합니다
  2. 서버측에서 해당 계정정보를 검증합니다.
  3. 계정정보가 정확하다면, 서버측에서 유저에게 signed 토큰을 발급해줍니다.
    여기서 signed 의 의미는 해당 토큰이 서버에서 정상적으로 발급된 토큰임을 증명하는 signature 를 지니고 있다는 것입니다
  4. 클라이언트 측에서 전달받은 토큰을 저장해두고, 서버에 요청을 할 때 마다, 해당 토큰을 함께 서버에 전달합니다.
  5. 서버는 토큰을 검증하고, 요청에 응답합니다.

웹서버에서 토큰을 서버에 전달 할 때에는, HTTP 요청의 헤더에 토큰값을 포함시켜서 전달합니다.

토큰의 장점

무상태(stateless) 이며 확장성(scalability)이 있다

이 개념에 대해선 지금 반복적으로 이야기하고 있죠? 이는 그만큼 토큰 기반 인증 시스템의 중요한 속성입니다. 토큰은 클라이언트사이드에 저장하기때문에 완전히 stateless 하며, 서버를 확장하기에 매우 적합한 환경을 제공합니다. 만약에 세션을 서버측에 저장하고 있고, 서버를 여러대를 사용하여 요청을 분산하였다면, 어떤 유저가 로그인 했을땐, 그 유저는 처음 로그인했었던 그 서버에만 요청을 보내도록 설정을 해야합니다. 하지만, 토큰을 사용한다면, 어떤 서버로 요청이 들어가던, 이제 상관이 없죠.

보안성

클라이언트가 서버에 요청을 보낼 때, 더 이상 쿠키를 전달하지 않음으로 쿠키를 사용함으로 인해 발생하는 취약점이 사라집니다. 하지만, 토큰을 사용하는 환경에서도 취약점이 존재 할 수 있으니 언제나 취약점에 대비해야 합니다(참조).

Extensibility (확장성)

여기서의 확장성은, Scalability 와는 또 다른 개념입니다. Scalability 는 서버를 확장하는걸 의미하는 반면, Extensibility 는 로그인 정보가 사용되는 분야를 확장하는것을 의미합니다. 토큰을 사용하여 다른 서비스에서도 권한을 공유 할 수 있습니다. 예를 들어서, 스타트업 구인구직 웹서비스인 로켓펀치에서는 Facebook, LinkedIn, GitHub, Google 계정으로 로그인을 할 수 있습니다. 토큰 기반 시스템에서는, 토큰에 선택적인 권한만 부여하여 발급을 할 수 있습니다 (예를들어서 로켓펀치에서 페이스북 계정으로 로그인을 했다면, 프로필 정보를 가져오는 권한은 있어도, 포스트를 작성 할 수 있는 권한은 없죠)

여러 플랫폼 및 도메인

서버 기반 인증 시스템의 문제점을 다룰 때 CORS 에 대하여 언급 했었죠? 어플리케이션과 서비스의 규모가 커지면, 우리는 여러 디바이스를 호환 시키고, 더 많은 종류의 서비스를 제공하게 됩니다. 토큰을 사용한다면, 그 어떤 디바이스에서도, 그 어떤 도메인에서도, 토큰만 유효하다면 요청이 정상적으로 처리 됩니다. 서버측에서 어플리케이션의 응답부분에 다음 헤더만 포함시켜주면 되지요.

Access-Control-Allow-Origin: *

이런 구조라면, assets 파일들(이미지, css, js, html 파일 등)은 모두 CDN 에서 제공을 하도록 하고, 서버측에서는 오직 API만 다루도록 하도록 설계 할 수도 있지요.

웹 표준 기반

토큰 기반 인증 시스템의 구현체인 JWT는 웹 표준 RFC 7519 에 등록이 되어있습니다. 따라서 여러 환경에서 지원이 되며 (.NET, Ruby, Java, Node.js, Python, PHP …) 수많은 회사의 인프라스트럭쳐에서 사용 되고 있습니다 (구글, 마이크로소프트 …)

출처 : https://velopert.com/2350

 

JWT란? 

기본 정보

JSON Web Token (JWT) 은 웹표준 (RFC 7519) 으로서 두 개체에서 JSON 객체를 사용하여 가볍고 자가수용적인 (self-contained) 방식으로 정보를 안전성 있게 전달해줍니다.

수많은 프로그래밍 언어에서 지원됩니다

JWT 는 C, Java, Python, C++, R, C#, PHP, JavaScript, Ruby, Go, Swift 등 대부분의 주류 프로그래밍 언어에서 지원됩니다.

자가 수용적 (self-contained) 입니다

JWT 는 필요한 모든 정보를 자체적으로 지니고 있습니다. JWT 시스템에서 발급된 토큰은, 토큰에 대한 기본정보, 전달 할 정보 (로그인시스템에서는 유저 정보를 나타내겠죠?) 그리고 토큰이 검증됐다는것을 증명해주는 signature 를 포함하고있습니다.

쉽게 전달 될 수 있습니다

JWT 는 자가수용적이므로, 두 개체 사이에서 손쉽게 전달 될 수 있습니다. 웹서버의 경우 HTTP의 헤더에 넣어서 전달 할 수도 있고, URL 의 파라미터로 전달 할 수도 있습니다.



 Json Web Token : JWT 는 JSON Web Token의 약자로 전자 서명 된 URL-safe (URL로 이용할 수있는 문자만 구성된)의 JSON입니다.

일반 JSON에서는 발급된 토큰의 만료를 시킬 수단이 없고, 관리할 수 있는 방법이 없다.
그래서 클레임* 기반 토큰으로 발급한다.

 JWT 구조는 헤더, 페이로드, 서명으로 되어있다.

헤더에는 토큰타입과 암호 알고리즘 정보가 있다.
(헤더를 암호화 하는게 아니다. 토큰 검증시 사용.)
페이로드에는 클레임에 관한 정보들이 있다. (Base64로 인코딩한다. 암호화가 아니다)
서명에는 누구나 위변조 할수 있기 때문에 Signature부분이 있다.
 JSON 헤더랑 JWT Claim Set(페이로드)만으로 encode를 한다면 누구나 다시 이값을 decode할수가 있기 때문이다.
출처: https://gist.github.com/LeoHeo/c9678154b1dadd85add5862b30e969f8

그래서 시크릿키와 함께 만든다. 시크릿키가 있으면 복호화할 수 없다.
출처 : https://tansfil.tistory.com/58

JWT 의 생김새

JWT 는 . 을 구분자로 3가지의 문자열로 되어있습니다. 구조는 다음과 같이 이루어져있습니다:


1. Header
 

typ: 토큰의 타입을 지정합니다. 바로 JWT 이죠.

alg: 해싱 알고리즘을 지정합니다.  해싱 알고리즘으로는 보통 HMAC SHA256 혹은 RSA 가 사용되며, 이 알고리즘은, 토큰을 검증 할 때 사용되는 signature 부분에서 사용됩니다.

2. Payload

토큰에 담을 정보가 들어있습니다. 여기에 담는 정보의 한 ‘조각’ 을 클레임(claim) 이라고 부르고, 이는 name / value 의 한 쌍으로 이뤄져있습니다. 토큰에는 여러개의 클레임 들을 넣을 수 있습니다.

클레임 의 종류는 다음과 같이 크게 세 분류로 나뉘어져있습니다:

등록된 (registered) 클레임,
공개 (public) 클레임,
비공개 (private) 클레임

3. 서명(signature)
이 서명은 헤더의 인코딩값과, 정보의 인코딩값을 합친후 주어진 비밀키로 해쉬를 하여 생성합니다.

출처: https://velopert.com/2389

 


JWT를 사용하는 이유?


Cors를 해결하기 위해 사용한다.
Web, Mobile 등 다양한 클라이언트를 지원해야하는 경우 생김
스케일 아웃했을 때 서버마다 다른 세션 파일이 생성됨
등등 아래 출처에서 자세히  볼 수 있다.
출처 :https://sanghaklee.tistory.com/47


만약에 Android / iOS 모바일 어플리케이션을 개발 한다면, 안전한 API 를 만들기 위해선 쿠키같은 인증시스템은 이상적이지 않습니다. (쿠키 컨테이너를 사용해야하죠). 토큰 기반 인증을 도입한다면, 더욱 간단하게 이 번거로움을 해결 할 수 있습니다.

 토큰은 클라이언트사이드에 저장하기때문에 완전히 stateless 하며, 서버를 확장하기에 매우 적합한 환경을 제공합니다


https://velopert.com/2350


JWT 장단점



장점 : 상태가 필요하지 않다 (Stateless)
단점 : JWT는 한 번 발급되면 돌이킬 수 가 없다 (만료기간까지 계속 이용가능)
암호화하지않고 인코딩하기때문에 페이로드 정보가 제한적이다.
JWT의 길이가 길어서 인증 요청이 많아질 수록 서버의 자원낭비가 생길수 있다.(이건 크기를 보고 따로 확인해봐야할 사항)

출처 :https://sanghaklee.tistory.com/47


Refresh Token



탈취 당할경우 보안에 취약, 유효기간을 늘릴 수 없음.
짧으면 자주 발급받아야함.

그래서 처음에 로그인을 완료했을 때 Access Token과 동시에 발급되는 Refresh Token같이 만들어줌.

Refresh Token 은 긴 유효기간을 가지면서,  Access Token이 만료됐을 때 새로 발급해주는 열쇠가 됨
=> Access Token을 리프레시하는데 필요한 토큰이라는 뜻

출처 : https://tansfil.tistory.com/59?category=255594

* 클레임 : 사용자 정보나 데이터 속성들을 의미한다.
출처 : https://elfinlas.github.io/2018/08/12/whatisjwt-01/

 

JWT(JSON Web Token) 이란?

인증과 토큰 그리고 JWT?최근들어 보안 및 인증을 위해서 JWT를 사용하게 되었다.그래서 사용만 하다가 이번에 JWT에 대한 개념과 구조, 사용법과 문제점 등을 알아보고자 한다. 일반 토큰 기반의 인증과 클레임(Claim) 토큰 기반 인증일반 토큰 기반은 과거에 많이 사용하던 방식이다.주로 의미가 없는 문자열(Random string) 기반으로 구성되어

elfinlas.github.io





OAuth

인증정보를 다른 어플리케이션으로 전달


OAuth는 인터넷 사용자들이 비밀번호를 제공하지 않고 다른 웹사이트 상의 자신들의 정보에 대해 웹사이트나 애플리케이션의 접근 권한을 부여할 수 있는 공통적인 수단으로서 사용되는, 접근 위임을 위한 개방형 표준이다.[1] 이 매커니즘은 여러 기업들에 의해 사용되는데, 이를테면 아마존,[2] 구글, 페이스북, 마이크로소프트, 트위터가 있으며 사용자들이 타사 애플리케이션이나 웹사이트의 계정에 관한 정보를 공유할 수 있게 허용한다.


출처 : https://ko.wikipedia.org/wiki/OAuth


OAuth는 Open Authorization, Open Authentication 뜻하는 것으로 애플리케이션(페이스북,구글,트위터)(Service Provider)의 유저의 비밀번호를 Third party앱에 제공 없이 인증,인가를 할 수 있는 오픈 스탠다드 프로토콜이다.
OAuth 인증을 통해 애플리케이션 API를 유저대신에 접근할 수 있는 권한을 얻을 수 있다. OAuth가 사용되기 전에는 외부 사이트와 인증기반의 데이터를 연동할 때 인증방식의 표준이 없었기 때문에 기존의 기본인증인 아이디와 비밀번호를 사용하였는데, 이는 보안상 취약한 구조였다. 유저의 비밀번호가 노출될 가망성이 크기 때문이다. 그렇기 때문에 이 문제를 보안하기 위해 OAuth의 인증은 API를 제공하는 서버에서 진행하고, 유저가 인증되었다는 Access Token을 발급하였다. 그 발급된 Access token으로 Third party(Consumer)애플리케이션에서는 Service Provider의 API를 안전하고 쉽게 사용할 수 있게 되었다.

출처 : https://minwan1.github.io/2018/02/24/2018-02-24-OAuth/

 

jwt 지문인식 도어락 같은 것(토큰의 종류), oauth : 친구집 문을 통해서 우리집으로 들어올 수 있게 해주는 것 (인증의 방식)
jwt 

' Theory' 카테고리의 다른 글

Decorator 패턴  (0) 2020.06.30
좋은 글 정리  (0) 2020.02.17
쿠키, 세션, 로컬 스토리지, 세션스토리지, indexedDB, 캐시  (0) 2019.11.27
slack trello 연동하기  (0) 2019.09.27
브라우저  (0) 2019.05.22