Dyrandy

OAuth 2.0 Fundamental Concepts and History (OAuth 2.0 기초) 본문

Concept Study/Web

OAuth 2.0 Fundamental Concepts and History (OAuth 2.0 기초)

Dyrandy 2021. 10. 4. 11:54

OAuth 2.0

  • Dyrandy

Intro

OAuth 2.0에 대하여 인터넷을 검색하고 글을 읽다보면 조금씩 용어들과 개념이 다르다는 것을 알 수 있다. 그만큼 OAuth는 굉장히 어려운 개념이고, 그 활용도가 고정되어 있지 않다. OAuth에 관하여 Youtube를 보다, 정말 유용하고, 개념과 용어들을 정말 쉽게 잘 풀어서 설명해주는 강의가 있어, 이 강의를 번역하여 공유하고자 한다.

https://www.youtube.com/watch?v=996OiexHze0&ab_channel=OktaDev

또한 이 자료와 함께 다른 사이트도 참조하면서 알게된 내용들을 추가하였다.

Abstract

웹의 발전으로 많은 웹 페이지가 늘어남에 따라, 다양한 인증 및 인가 방식이 만들어 졌다. OAuth를 흔히들 '인증, Authentication'을 위한 하나의 Framework라고 생각하지만, OAuth 2.0의 본래의 목적은 '인가, Authorization'이다. (인증과 인가에는 엄연한 차이가 존재한다.)

https://velog.io/@aaronddy/인증Authentication과-인가Authorization

OAuth 2.0를 간단하게 간략하게 소개하자면,

  • A라는 서비스를 사용하고자 하는 사용자가 있다고 하자. 이 사용자는 A라는 서비스를 이용하고자 하는데, A라는 서비스가 사용자의 B 서비스 계정 정보를 물어본다. A 서비스가 과연 안전한지, 내 계정을 안전하게 사용할 지 많은 의문을 갖게 된다. 이때 사용자가 A 서비스에 직접적으로 계정 정보를 입력하지 않고, B 서비스에 있는 사용자의 정보를 열람 할 수 있도록 권한을 A 서비스에 위임 해줘서, A 서비스가 B 서비스에서 사용자의 정보를 열람하는 것이 OAuth 2.0이다.

좀 더 살펴보기 전에 RFC문서에 있는 Diagram을 한번 보자.

Abstract Protocol Flow

A) Client는 Resource Owner에게 권한을 요청한다.

B) Resource Owner는 들어온 권한 요청이 유효한 요청인지 검증 후 유효하다면 권한 승일을 Client에게 응답으로 보낸다.

C) Client는 Authorization Server에 받은 권한 승인을 제시하여 Access Token을 요청한다.

D) Authorization Server는 유효한 권한이라 판단하면 Access Token을 Client에게 응답으로 전송한다.

E) Client는 Access Token을 Resource Server에 보냄으로써, 인가 받았다는 것을 증명한다.

F) Resource Server는 유효한 Access Token으로 검증을 수행하면 Resource를 응답으로 보내준다.

이렇게 보면 굉장히 복잡해 보이고, 이해하기 다소 어려움을 느낄 것이다. 설명이 이미 OAuth에 대해 어느 정도 알고 있음을 요구하는것 같다. 그래서 먼저 OAuth가 왜 탄생했고, 어떻게 이용되는지 High Level에서 먼저 보고, 용어들을 살펴보면서 더 깊게 들어가보자.

History

OAuth 2.0에 더 깊게 들어가기 전에, Web의 역사를 살펴볼 필요가 있다. 과거에는 웹에서 인가를 위임 할 때, 즉, A 서비스가 사용자의 B 서비스에 관한 정보를 물어볼 때 직접적으로 계정을 요구했다.

https://www.youtube.com/watch?v=996OiexHze0&ab_channel=OktaDev

위의 예시를 살펴보면 Yelp라는 사이트는 직접적으로 사용자의 이메일 계정을 물어보고있다. 과거에는 이렇게 인가를 위임하는 방식이 존재하지 않아 이런 경우가 흔했다.

OAuth 2.0 Top Down Approach

OAuth 2.0 Flow - 1 (Simplified)

OAuth 2.0을 매우 간단하게 살펴보자. (Facebook으로 예시를 들겠다)

  1. 사용자는 Test.com에 접근하고, Test.com은 Facebook의 친구목록과 사용자의 프로필 정보를 요청한다.
  2. 이를 통해 사용자는 Facebook Login Page(accounts.facebook.com)로 리다이렉트 되고, 해당 페이지에 Facebook의 계정정보를 입력하게 된다.
  3. Facebook은 Test 사이트에서 사용자의 친구목록과 사용자의 프로필 정보를 사용하고자 하는 것을 사용자에게 알리고, 인가를 허가하는지 물어본다.
  4. 만약, 인가를 허가 한다면, 다시 Test.com에 리다이렉트 될것이고, 허가를 허용하지 않는다면, 연결이 끊길 것이다.
  5. 허용된 인가를 통해 Test.com은 사용자의 Facebook 친구목록과 프로필을 갖고 올 것이다.

요기까지가 OAuth 2.0을 매우 간단하게 바라본 것이다. 조금 더 깊게 들어가기 전에 용어들을 살펴보자.

OAuth 2.0 Terminology - 1

OAuth 2.0을 깊게 알기 위해서는 용어들을 파악하는 것이 핵심이다. 용어들은 RFC(https://datatracker.ietf.org/doc/html/rfc6749)와 OktaDEV Youtube(https://www.youtube.com/watch?v=996OiexHze0&ab_channel=OktaDev)를 참고하였다.

  1. Resource Owner : Client가 사용하고자 하는 리소스의 주인을 뜻한다. 요기서 리소스의 주인은 사용자, 즉, 위 예시에서 Test.com을 사용하는 '사용자'를 뜻한다.
  2. Client : Yelp, Test.com 같은 리소스를 요청하는 사이트/서비스를 뜻한다.
  3. Authorization Server : 사용자의 인증을 수행하는 서버로서, Resource Server와 Authorization Server를 같이 보는 경우가 있고, 이를 따로 분리하는 경우도 있다. 위 예시에서는 Facebook에서 사용자가 인증하는 부분(accounts.facebook.com)이라고 생각하면 된다.
  4. Resource Server : 리소스가 저장된 서버다. 위 예시를 들면 Facebook 친구 목록과 사용자 프로필이 저장된 서버라고 생각하면 된다.
  5. Authorization Grant : 사용자가 Client에게 사용자의 리소스에 접근을 허용해준다는 것을 의미한다. 이것은 Token이 될 수 있고, 코드가 될 수 있다. (크게 4가지 종류가 있고, 처음에 이해하기 어려울 수 있다. 글을 읽다 보면 점차 이해가 될 것이다)
  6. Redirect URI : Callback이라고도 불리며, Authorization Server가 사용자를 어디로 다시 보내야하는지 명시 한 부분을 의미한다.
  7. Access Token : Client가 Resource Server에 인가를 허용 받았다는 것을 증명하기 위한 Key를 의미한다.

OAuth 2.0 Flow - 2 (Bit more detail)

  1. 사용자(Resource Owner)는 Test.com(Client)에 접속하는데 Test.com이 사용자의 Facebook 친구목록과 프로필을 사용하고자 Facebook 연결을 요청한다. 이때 accounts.facebook.com으로 요청을 보내면서 사용자가 인증이 끝나면 어디로 Redirect 시킬지 주소를 포함한 Redirect URI를 같이 보낸다. 또한 다른 정보들도 함께 보내는데, Response Type이라는 것도 보낸다. 이것은 Client가 어떤 Authorization Grant를 원하는지를 명시한 부분이다. 그림의 예시는 Code Authorization Grant를 요구하는 모습이다. (여러 종류의 Authorization Grant가 존재하며, 이를 후에 알아볼 것이다.)
  2. accounts.facebook.com(Authorization Server)에 접속한 사용자는 인증정보를 입력하고 사용자가 해당 계정의 주인임을 증명한다.
  3. accounts.facebook.com은 Test.com이 사용자의 친구목록과 프로필을 사용하자 하는것을 알리고 이를 허용할지에 대한 여부를 물어본다.
  4. 사용자가 인가를 허용했다면, accounts.facebook.com은 Test.com Callback에게 Authorization Code를 보낸다. 이때 Authorization Code로 Client가 할 수 있는건 Access Token으로 교환하는거 밖에 없다.
  5. Test.com은 Authorization Code를 사용해 Authorization Server에게 Access Token을 요구한다. Authorization Code를 Access Token으로 교환하는 것이다.
  6. Access Token을 받은 Test.com은 받은 Token을 이용하여 contacts.facebook.com(Resource Server)에 인가 받았음을 증명하고, 사용자의 친구목록과 프로필 정보를 제공받는다. 이때 만약 Client인 Test.com이 사용자의 친구목록을 지우거나, 업데이트하고자 한다면, contacts.facebook.com은 이를 거부할 것이다. 그 이유는 Access Token을 발급 받았다고 하더라도, 모든 권한이 주어진것이 아니라, 사용자가 허용한 권한만 제공받기 때문이다.

요기까지가 OAuth 2.0의 큰 흐름이라고 보면 된다. 이를 보면 굉장히 간단하고 어려운 내용이 없다. 근데 몇가지 의문점이 들것이다.

  • 사용자는 어떻게 무슨 권한이 Client가 요청하는지 알것이며, 어떻게 권한을 세분화해서 줄 수 있을까?
  • 왜 Access Token을 바로 받지 않고, 굳이 Authorization Code를 받게 할까?

OAuth 2.0 Teminology - 2 (with Scope & Consent)

  1. Scope : Authorization Server는 본인이 알아 들을 수 있는 Scope들을 리스트처럼 갖고 있다. 이것을 Contacts.Read, Contacts.Delete, Email.Write, 등 처럼 표현이 될 수 있다. 그리하여 Client가 Authorization Server에 요청을 보낼 때 본인이 필요로 하는 권한의 Scope를 정리해서 요청을 한다. (이를 정말 간단하게 표현하자면, '권한의 종류', '권한의 리스트' 라고 보면 된다.)
  2. Consent : Consent를 한국말로 표현하자면, '동의'로 번역된다. 대부분의 Client들은 권한을 Authorization Server에 요청하면, Authorization Server는 사용자에게 Client가 어떤 권한을 요구했으며, 이를 동의하는지 묻는 부분이 나온다. (아래 예시의 단계 3)

OAuth 2.0 Flow - 3 (with Scope & Consent)

  1. Test.com(Client)이 accounts.facebook.com(Authorization Server)으로 사용자를 보내면서 Test.com은 Redirect URI를 통해 동의가 끝나면 어디로 사용자를 보낼 것인지 명시한다. Response Type으로 어떤 Authorization Grant를 원하는지, Scope를 통해 어떤 권한들이 필요한지 명시 할 것이다.
  2. accounts.facebook.com에 접속한 사용자는 인증정보를 입력하고 사용자가 계정의 주인임을 증명한다.
  3. accounts.facebook.com은 사용자에게 Client가 어떤 권한들을 요청했는지 알리고 이에 대한 동의 여부를 묻고 응답을 받는다.
  4. 만약 사용자가 동의를 한다면, 받았던 Redirect URI로 사용자를 Redirection 시키고 Client는 Authorization Code를 받을 것이다.
  5. Test.com은 받은 Authorization Code를 accounts.facebook.com(Authorization Server)과 통신하여 Access Token으로 교환할 것이다.
  6. Access Token을 받은 Test.com은 contacts.facebook.com과 통신하여 프로필과 친구목록을 조회 할 것이다. 이때 이 Access Token은 친구목록과 프로필만 조회할 수 있도록 Scope가 제한되고, 이외의 기능 혹은 정보 열람은 허용하지 않을 것이다.
  • 그러면 다시 왜 굳이 Access Token을 바로 받지 않고? Authorization Code를 받는 것일까? 이를 이해하기 위해서는 먼저 Back Channel과 Front Channel에 대한 이해가 필요하다.

OAuth 2.0 Teminology - 3 (Back Channel & Front Channel)

  1. Back Channel : 굉장히 안정적인 통신 구간을 의미한다. 즉, 사용자 혹은 제 3자의 개입이 있을 가능성이 매우 적어 위변조의 가능성이 낮은 통신 구간을 의미한다. OAuth 2.0에서는 Authorization Server와 Client만 서로 통신하는 구간을 의미한다. 만약 사용자의 브라우저에 Authorization Code가 넘어간다면, 사용자에게 있는 어떠한 악성 프로그램이나, 감시 프로그램에 의해 이 Code가 Leak될 가능성이 있다.
  2. Front Channel : 안정적이지만, 위변조의 가능성이 존재해, 상대적으로 덜 안전한 통신 구간을 의미한다. 이는 사용자의 브라우저를 거치는 통신을 의미하며, 비록 안전하겠지만, 어떠한 개입이 있을 가능성이 있는 통신 구간을 뜻한다. 주로 이렇게 Front Channel을 통과하는 요청들의 정보는 GET Request의 Query Parameters에 정보가 담겨 있다.

OAuth 2.0 Flow - 4 (with Back & Front Channel)

  1. Test.com(Client)은 사용자(Resource Owner)에게 Facebook에서 로그인을 요청한다. 이때 Redirect URI, Response Type, Scope등을 정의하여 같이 보낸다. (Front Channel)
  2. 사용자는 accounts.facebook.com(Authorization Server)에서 로그인을 수행하여 본인임을 증명한다.
  3. accounts.facebook.com은 Test.com이 사용자의 친구목록 및 프로필에 접근하고자 하는 것을 알리고 동의 여부를 묻는다.
  4. 사용자가 동의를 한다면, Authorization Code를 들고 Redirect URI로 redirect된다. (Front Channel)
  5. Test.com은 Authorization Code를 들고 accounts.facebook.com과 통신하여 Authorization Code를 Access Token으로 교환한다. (Back Channel)
  6. Test.com은 contacts.facebook.com(Resource Server)에 Access Token을 이용하여 사용자로부터 친구목록과 프로필을 열람할 수 있는 권한을 위임받았음을 증명하고 정보 열람을 요청합니다.

요기까지가 OAuth 2.0을 High Level에서 바라본것이다. 아직 풀리지 않은 문제들이 존재하며 궁금증도 존재할 것이다. 한단계씩 구체적으로 살펴보자.

OAuth 2.0 In Detail

앞서 살펴보았던 그림을 다시 살펴보자

OAuth%202%200%2036fc2d9e734548d9ab5f68a3af027a85/Untitled%205.png

  • 위 그림을 기준으로 설명하지만, Step으로 명시된 번호와 그림에 나온 번호가 일치 하지 않다. (위 그림의 2번, 3번은 생략하였다.)

Step 1. The Beginning of the Flow

OAuth 2.0 Framework의 시작 부분은 항상 Client가 사용자에게 타 서비스로 연결을 요청하는것으로 시작한다. 이 요청의 URL은 어떻게 생겼을까?

  1. client_id : 이름에서 알 수 있듯이 요청을 날리는 Client의 ID를 명시한 Parameter다. client_id는 처음 Client가 예를 들면 Google에 자기 자신을 등록할 때 발급 받는 값이다.

  • 이때 secret_token이라는 것도 같이 발급되는데, 이것을 중요한 정보로 Access Token을 얻고자 Back Channel Request를 진행할 때 Client가 본인임을 증명할 때 사용된다.
  1. redirect_uri : Authorization Server에서 Resource Owner가 인증 프로세스를 마치면 어디로 Redirect될지 명시한 Parameter다.
  2. scope : Client가 어떤 권한들을 요청하는지 명시한 부분이다.
  3. response_type : 이것은 어떤 타입의 Grant를 서버에게 요청하는지 나타내는 부분이다. 가장 보편적으로 사용되는 것은 Code이고 이 "Code"를 사용하는 OAuth 흐름을 Authorization Code Flow라고도 불린다. Code방식은 Web에서 가장 보편적으로 쓰이며, PKCE(Proof Key for Code Exchange)와 함께 Mobile에서도 함께 사용된다. (참고 : 널리 4개, Code, Implicit, Resource Owner Password Credentials, Client Credentials가 주로 사용되지만, 서버마다 자신만의 방법을 추가하여 사용하기도 한다.)
    https://datatracker.ietf.org/doc/html/rfc6749#section-1.3
  4. state : 보안을 위해 사용되는 값이다. 만약 이 값이 설정되어있다면, Response URI에 이 부분이 함께 포함되어 날라온다.

Step 2. After the Consent

사용자가 Client가 본인의 친구목록과 프로필에 접근하는 것을 허용 했다는 가정하면 다음과 같은 URL로 사용자는 Redirect 될것이다.

요기서 Rediret URL은 앞서 처음 Request URL에 있던 redirect_uri라는 것을 알 수 있다.

  1. code : 처음 요청했을 때 response_type에 code를 명시한 것이, 이 code를 발급받기 위함이었다. 추후에 이 code를 이용하여 Access Token을 발급 받을 것이다.
  2. state : 앞서 말했던 보안을 위해 사용되는 값으로, 이 값은 처음 요청을 날렸을 때 사용된 값이다. 이 값은 항상 같아야하며 Response가 돌아올 때 바뀌면 안된다.

Step 3. Exchanging the Code for an Access Token

이 단계에서는 Client는 본인이 받은 code를 이용하여 Access Token을 요청하는 단계다. 이때 완전히 일치하는 Authorization Server일 수도 있지만, 보통은 약간 다른 End-Point고 이 End-Point를 Token End-Point라고도 불린다.

  1. code : 앞서 Authorization Server가 전송해줬던 Code다.
  2. client_id : 이름에서 알 수 있듯이 Client가 본인임을 나타내는 ID다.
  3. client_secret : 처음 Client가 Authorization Server에게 자기 자신을 등록할 때 client_id와 함께 받은 값으로, Client 본인이 요청을 날리는 것을 인증하기 위한 매우 중요한 값이다.
  4. grant_type : Grant의 여러 종류 중 하나를 나타내는 값으로, 통상적으로 제일 많이 쓰이는 것은 Authorization Code(aka, Code)다.

Step 4. Response with Access Token

위에서 요청을 날리게 되면 아래와 같은 Response가 돌아오게될 것이다.

  1. access_token : Client가 Resource Server와 통신할 때 필요로 하는 Token으로 인가를 위임받았다는 것을 증명하는 토큰이다.
  2. expires_in : 해당 토큰이 유효한 시간을 나타내는 값이다.
  3. token_type : 해당 토큰의 종류를 나타내는 값이다.

Step 5. Using the Access Token

이제 마지막 단계는 Client가 얻은 Access Token을 이용해서 Resource Server에 접근하는 것이다. 아래와 같이 Token을 Type과 함께 Authorization Header안에 넣어서 요청을 날린다.

이때 Token을 이용해서 Client가 요청을 날리지만, API End Point가 권한이 있는지 없는지 여부를 확인한다. 비록 Token은 Valid 토큰 일지라도, Delete 권한이 없는 상태에서 요청이 들어온다면, API End Point가 검증을 하고 요청을 거부해야한다.

Different Types Of Grant

앞서 Response Type, 즉, Grant Type에는 여러 종류가 있음을 언급하였다. 각 서비스마다 자기 만의 Reponse Type이 존재할 것이지만, 통상적으로 가장 많이 쓰이는 4가지를 적어보았다.

  1. Authorization Code : 이제까지 봐왔던 예시의 Code Type이다. 이 요청은 Front Channel과 Back Channel 두 가지를 활용하여 요청을 진행한다. 가장 많이 쓰이는 Type이다.
  2. Implicit : Back Channel이 없을 때 사용된다. 이 방법은 Back Channel이 없기 때문에 굳이 Code Exchange가 필요 없다. 그리하여 Code Exchange Process가 없으므로, Code를 발급 받는 것이 아니라, Access Token을 즉시 발급 받는다. (보통 순수 JS로 만들어진 페이지들, 즉, Back End가 없는 사이트들이 사용하는 방법이다)

Implicit Flow Diagram

  1. Resource Owner Password Credentials : 이 방법은 Back Channel에서만 사용되는 Process로, 앞서 두 예시와는 다르게 거의 사용되지 않는다. 이 방법은 Resource Owner의 계정정보를 Authorization Server에 보내 Access Token을 발급 받는 방법이다.
  2. Client Credentials : 이 방법도 위 방법과 동일하게 Back Channel에서만 사용되고, 거의 사용되지 않는다. 이 방법은 보통 Machine 대 Machine이 사용하는 방법으로, Client 본인의 계정정보를 사용하여 Access Token을 발급 받는 방법이다.

OAuth 2.0 as Authentication?

OAuth 2.0을 공부하다 보면, 인가를 위한 방법이 아니라, 인증을 위해 사용된다는 말이 있다. 이 말도 전혀 틀린 말이 아니다. OAuth 2.0이 처음 나왔을 당시 상당한 인기를 끌었다. 많은 서비스들이 이 OAuth 2.0을 사용하기 시작했다. 그러나 OAuth 2.0은 인가를 위임하기 위해 사용되었지만 다양한 서비스들은 아래와 같은 다양한 목적들을 위해 사용했다.

  1. Simple Login - 인증, Authentication
  2. Single Sign-On Across Sites - 인증, Authentication
  3. Mobile App Login - 인증, Authentication
  4. Delegated Authorization - 인가, Authorization (본래 목적)

불행하게도 OAuth 2.0은 "인증"을 위해 설계되지 않았다. OAuth 2.0은 Scope를 위해 정의되었다. 즉, 사용자의 제한된 정보들을 끄집어서 사용하고자 만들어진것이다. OAuth 2.0은 사용자가 누군지에는 관심이 없었고, 오로지 제한된 정보에 접근하기 위해 사용되었다. 그러나 인증을 허용하고 있다는 것이 이 OAuth 2.0이 정말 복잡하게 만드는 것이다. 그래서 인터넷 여러 곳을 돌아다니다 보면, 각기 다른 설명과 각기 다른 용어들을 사용한다. 다음은 OAuth 2.0이 "인증, Authentication"을 위해 사용되면 발생하는 문제들이다.

  1. 사용자의 정보를 갖기 위한 표준이 없다.
  2. 모든 인증 방법은 각기 다른 방법이고, 기준이 없다.
  3. 공통 Scope의 범위가 없다.

OAuth 2.0은 본래 인가를 위해 만들어졌다. 그러나 각 사이트 및 서비스 마다 자기만의 "특별한 방법"을 탑재하여 OAuth 2.0을 인증을 위해 사용하고 있었다. 모든 방법들이 서비스 별로 조금씩 달랐고, 상호 운용이 불가능했다.

그리하여 많은 사람들이 OAuth 2.0을 이용하고, 이를 바꾸지 않는 선에서, 인증을 허용하는 방법을 구상하기 시작했다. 그리고 OAuth 2.0위에 OpenID Connect라는 것을 탑재하여, OAuth 2.0의 인증 문제를 해결했다.

OpenID Connect

사실 OpenID는 별도의 다른 Framework라고 하기엔 OAuth 2.0에 큰 비중을 차지고 하고 있지 않다. 단지 OAuth 2.0을 인증을 위해 사용한다면, 추가 단계를 거치라는 것을 명명하고 있다.

그러면 OpenID Connect는 OAuth 2.0에 무엇을 추가할까?

  1. ID Token : ID Token은 Access Token을 발급 받을 때 같이 발급받는다. ID Token에는 사용자에 대한 정보가 담겨 있다.
  2. 사용자 정보를 더 가져올 수 있는 End-Point : 만약 ID Token만으로 정보가 부족하면, 특정 End-Point로 가서 사용자에 대한 정보를 더 가져올 수 있게 해주는 곳이다. (OpenID Connect가 구현된 모든 곳에는 이런 End-Point가 존재한다)
  3. 표준 Scope
  4. 표준화된 구현

OpenID Connect가 구현된 곳에서는 Access Token을 요청하는 구간에서 ID Token 또한 요청할 수 있다.

OAuth 2.0 Flow - 5 (with OpenID Connect)

위 그림을 보면 전과 거의 바뀐 것이 없다는 것을 알 수 있다. 달라진 점이라 하면, 1단계에서 Scope에 openid가 들어가는 것과, 5단계에 Authorization Code를 이용해 Access Token과 ID Token둘다 발급받는 것이다.

이렇게 OpenID Connect는 별도의 Framework가 아니라, OAuth 2.0의 일부분이라 봐도 무방하다.

요기서 ID Token은 무엇일지 궁금해하는 사람들이 많을 것이다. 이 ID Token은 JWT(Json Web Token)이라는 것인데 이것은 다른 포스트에 정리하도록 하겠다.

Wrap Up

OAuth 2.0 사용도

  • API에 접근을 인가하기 위해
  • 사용자의 정보를 다른 시스템에서 사용하는 것을 인가하기 위해

(인가, Authorization)

OpenID Connect 사용도

  • 사용자의 Login
  • 사용자의 계정을 다른 시스템에서 사용할 수 있게 해주는 것

(인증, Authentication)

참고

https://oauth.net/2/

https://velog.io/@undefcat/OAuth-2.0-간단정리

https://datatracker.ietf.org/doc/html/rfc6749

https://auth0.com/docs/protocols/protocol-oauth2

https://www.oauth.com/

Comments