hongcheol / CS-study

cs지식을 정리하는 공간
MIT License
242 stars 30 forks source link

JWT & OAuth #114

Open khyunjiee opened 2 years ago

khyunjiee commented 2 years ago

Token

프로그래밍 언어에서의 토큰은 문법적으로 더 이상 나눌 수 없는 기본적인 언어요소를 말한다.

예를 들어 하나의 키워드나 연산자 또는 구두점 등이 토큰이 될 수 있다.

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

토큰 기반 시스템은 stateless 하다. 무상태, 즉 상태유지를 하지 않는다는 것이다.

토큰 기반의 시스템에서는 유저의 인증 정보를 서버나 세션에 담아두지 않는다.

세션이 존재하지 않으니 유저들이 로그인 되어있는지 안되어있는지 신경 쓰지 않으면서 서버 확장이 가능해질 것이다.

대략적인 플로우

image

  1. 유저가 아이디와 비밀번호로 로그인

  2. 서버에서 해당 계정의 정보를 검증

  3. 계정 정보가 정확하다면 서버에서 유저에게 signed 토큰을 발급

    → signed : 해당 토큰이 서버에서 정상적으로 발급된 토큰임을 증명하는 signature를 지니고 있다는 뜻

  4. 클라이언트에서 전달받은 토큰을 저장해두고, 서버에 요청할 때마다 해당 토큰을 함께 서버에 전달

  5. 서버는 토큰을 검증하고 요청에 응답

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

토큰의 장점

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

반복적으로 나온 개념인데, 토큰 기반 인증 시스템의 중요한 속성이다.

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

만약 세션을 서버 측에서 저장하고 있고, 여러 서버를 사용해 요청을 분산했다면 어떤 유저가 로그인했을때는 그 유저는 처음 로그인했었던 서버에만 요청을 보내도록 설정해야 한다.

하지만 토큰을 사용한다면, 어떤 서버로 요청이 들어가든지 상관없게 된다.

보안성

클라이언트가 서버에 요청을 보낼 때, 더 이상 쿠키를 전달하지 않음으로 쿠키를 사용함으로 인해 발생하는 취약점이 사라진다.

(쿠키는 클라이언트 로컬에 저장되기 때문에 변질되거나 요청에서 스니핑당할 위험이 있다.)

하지만, 토큰을 사용하는 환경에서도 취약점이 존재할 수 있으니 대비해야 한다.

확장성 exensibility

여기서의 확장성은 처음의 scalability 와는 다르다.

scalability 는 서버 확장을 의미하는 반면, extensibility 는 로그인 정보가 사용되는 분야를 확장하는 것을 의미한다.

토큰을 사용해 다른 서비스에서도 권한을 공유할 수 있다.

여러 다른 웹 사이트들의 로그인을 형태를 살펴보면 구글, 페이스북, 카카오, 네이버 등의 계정으로 로그인이 가능한 사이트들이 많은 것을 보면 알 수 있는 사실이다.

토큰 기반 시스템에서는 토큰에 선택적인 권한만 부여해 발급할 수 있다.

(예시로 어떤 사이트에서 페이스북으로 로그인했다면 프로필 정보는 가져올 수 있어도 페이스북에 글을 작성할 수 있는 권한은 없다.)

여러 플랫폼 및 도메인

어플리케이션과 서비스의 규모가 커지면, 여러 디바이스를 호환시키고 더 많은 종류의 서비스를 제공하게 된다.

토큰을 사용한다면 어떤 디바이스던지 어떤 도메인이던지 토큰만 유효하다면 요청이 정상 처리된다.

JWT란?

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

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

자가 수용적이란? (self-contained)

JWT필요한 모든 정보를 자체적으로 지니고 있다.

JWT 시스템에서 발급된 토큰은 토큰에 대한 기본 정보, 전달할 정보, 토큰의 검증 여부인 signature 등을 포함하고 있다.

따라서 서버와 클라이언트 사이에서 손쉽게 전달될 수 있으며, 웹 서버의 경우 HTTP 헤더에 넣어서 전달하거나 URL의 파라미터로 전달할 수도 있다.

URL-safe란?

Base 64 Encoding with URL and Filename Safe Alphabet 형식으로 주로 base64url 인코딩으로 불린다.

쉽게 말해서 사용되는 JSON 데이터가 URL에 포함될 수 있는 문자만으로 만든다는 것이다.

JWT 작동 원리

image

  1. 사용자가 아이디와 비밀번호를 입력해 로그인
  2. 서버는 요청을 확인하고 secret key를 통해 Access token 발급
  3. 이후 JWT가 요구되는 API를 요청할 때 클라이언트가 Authorization 헤더에 Access token을 담아 보냄
  4. 서버는 JWT Signature 를 체크하고 Payload 로부터 유저의 정보를 확인해 데이터를 리턴

JWT 구조

image

JWT 사용 이유

만약 Android , iOS 모바일 어플리케이션을 개발한다면, 안전한 API를 위해 쿠키와 같은 인증 시스템은 인상적이지 않다.

토큰 기반 인증을 도입한다면, 더욱 간단하게 번거로움을 해결할 수 있다.

또한 클라이언트 측에서 저장하기 때문에 완전히 stateless 하며 서버를 확장하기 적합한 환경을 갖춘다.

JWT 장단점

장점

단점

Refresh Token

유효기간을 늘릴 수 없으며, 짧으면 토큰을 자주 발급받아야 한다.

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

Refresh token은 긴 유효기간을 가지면서, Access token이 만료됐을 때 새로 발급해주는 열쇠 역할을 한다.

즉, Access token을 리프레시하는데 필요한 토큰이라는 것이다.

OAuth

Open Authorization, Open Authentication 을 뜻하는 것으로 애플리케이션(페이스북, 구글, 트위터 등의 Service Provider) 유저의 비밀번호를 Third-Party 앱에 제공 없이 인증, 인가를 할 수 있는 오픈 스탠다드 프로토콜이다.

OAuth 인증을 통해 애플리케이션 API를 유저 대신에 접근할 수 있는 권한을 얻을 수 있다.

OAuth가 사용되기 전에는 외부 사이트와 인증 기반의 데이터를 연동할 때 인증 방식의 표준이 없었기 때문에 기존의 기본 인증인 아이디와 비밀번호를 사용했지만 이것은 보안상 취약하다.

유저의 비밀번호가 노출될 가능성이 크기 때문이다.

이 문제를 보완하기 위해 OAuth의 인증은 API를 제공하는 서버에서 진행하고, 유저가 인증되었다는 Access Token을 발급했다.

발급 받은 Access token으로 써드 파티앱에서는 Service Provider의 API를 안전하고 쉽게 사용할 수 있다.

즉, 인증 정보를 다른 어플리케이션으로 전달한다. (구글, 페이스북, 트위터 등)

JWT와 OAuth의 차이점

JWT는 토큰의 한 형식이고, OAuth는 하나의 프레임워크이다. 따라서 둘을 비교하는 것은 맞지 않는 접근이다.

프레임워크란,

을 뜻하고, JWT는 이런 프레임워크에서 발생하는 산출물이다.

OAuth token은 어떤 사용자의 정보 등과 같은 중요한 정보를 가진 명확한 토큰이 아니다.

그래서 이 OAuth token을 사용하는 개발자가 이 토큰이 갖고 있는 정보에 대해 아는 것이 전혀 없다.

이 모호한 OAuth token이 갖고 있는 정보는 일련의 랜덤 문자열인데 이것은 일종의 포인터이다.

즉 OAuth framework로 들어가서 해당 정보가 저장되어 있는 주소를 확인할 수 있는 포인터이다.

반대로 JWT는 포인터 또는 모호한 토큰이 아니다.

JWT가 스스로 유효성 검사를 한다고 하는 것들은, 개발자가 토큰의 내부 속성 정보를 활용해 유효성 검사를 할 수 있음을 얘기하는 것이다. 이것은 취약점으로 작용할 수도 있다.

Reference

https://velopert.com/2389 http://www.opennaru.com/opennaru-blog/jwt-json-web-token/ https://ko.wikipedia.org/wiki/OAuth

khyunjiee commented 2 years ago
  1. 토큰 기반 인증 vs 세션 기반 인증
  2. JWT를 설명하고 세션 기반 인증에 비해 장점은 어떤것인지?