OAuth

흔히 말하는 SNS Login기능은 국제표준으로 자리잡은 OAuth2.0 기술을 따라 진행되게 되어있다. OAuth를 알아보면서 개인프로젝트를 하면서 SNS Login 기능을 개발했던 내용을 다루어본다. 시작하자!🚀

개인프로젝트 주소

OAuth 탄생배경

요즘 시대의 우리는 아래와 같은 로그인 화면에서 다양한 소셜 미디어를 이용한 로그인 기능을 당연시 생각하는 사회에 살고 있다. 아래 사진에서 Login 버튼 밑에 있는 구글 로고 버튼을 누르면 어떤 동작을 할지 굳이 그 버튼을 눌러보지 않아도 유추가 가능하다고 생각하신다면 내 말에 공감할 것이다. 아마 버튼을 누르면 웹으로 현재 실행중인 앱에서 프로필, 이메일주소, 이름 등에 접근하고 싶은데 괜찮나요? 라고 묻고 당신이 괜찮다라고 허락해주면 해당 소셜 미디어에서 현재 사용 중인 앱으로 정보를 제공해줄 것이다. (어떻게 하는거지..?? 😏)

지금은 없으면 이상한 소셜 미디어 로그인 기능

당신에게 묻고싶다. 구글 로고 버튼을 눌렀을 때 어떤 화면이 나오길 기대했는가? 만약, 아래와 같은 또 다른 로그인 창이 나온다고 생각해본적 있는가?

절대로 라는 말이.. 더 의심스럽게 만든다. 🤔

OAuth가 없던 시절에 지금과 같이 어떠한 앱에서 다른 앱의 정보를 가져올 수 있는 방법은 직접 로그인 뿐이였다. 우린 지금 사용하려는 앱에서 다른 앱의 서비스를 이용하기 위해 그들을 믿고 우리의 아이디와 비밀번호를 넘겨 주었어야 한다. 이건 아래의 2가지 문제점이 있다.

  • 사용자 입장 : 내 아이디와 비밀번호를 어떻게 믿고 전달하지..??
  • 개발자 입장 : 내가 사용자에게 받은 정보를 혹시나..!! 유출 당하면? 나의 운명은..?? 😇

사용자나 개발자나 그 누구에게도 좋은 방법이 아니다 이건 누굴 위한 것인가!? 이러한 문제를 각 기업에선 각자의 방식대로 해결을 하였고 기업마다 각각의 방식으로 이 문제를 해결하였다. 예를들어 구글의 AuthSub, AOL의 OpenAuth, 아마존의 웹서비스 API 등이 있다. 이 대목에서 나는 이런 그림이 떠올랐다.

따로 표준이 없었던 핸드폰 충전선들🤔 (이미지는 예시이다)

이러한 이유로 똑똑한 사람들이 2006년에 OAuth의 시초를 시작했다고 한다. 아래의 글은 위키피디아에서 발췌한 OAuth의 역사이다.

2006년 11월 블레인 쿡은 트위터에 OpenID를 탑재하는 작업을 하고 있었다. 같은 시기, 소셜 북마크 사이트인 Ma.gnolia는, 회원이 OpenID를 사용하여 대시보드 위젯으로 서비스에 접속할 수 있는 인증 방법을 필요로 하고 있었다. 이에 쿡, 크리스 메시나, 래리 하프(Ma.gnolia)는 데이비드 리코던(당시 베리사인)과 만나 OpenID를 활용해 트위터나 Ma.gnolia의 API로 인증을 위임하는 방법을 논의했다. 그 결과, API 접근 위임에 대한 공개 표준이 아직 존재하지 않는다는 결론에 이르렀다.

OAuth의 인터넷 커뮤니티는 2007년 4월에 탄생하여, 소수 인원으로 새로운 공개 프로토콜의 초안을 썼다. OAuth 프로젝트를 알게 된 구글의 드위트 클린턴은 지원을 표명했다. 2007년 7월, 팀은 사양 초안을 완성시켰다. 에런 해머래해브가 가세하여 많은 협력자들의 조정을 실시하여, 보다 정식적인 사양을 작성해나갔다. 2007년 10월 3일, OAuth 코어 1.0의 최종 초안이 발표되었다.

2008년 11월, 미네아폴리스에서 열린 제73회의 IETF 회합에서 OAuth의 비공식 회합도 열려 새로운 표준화를 향해 IETF에 OAuth 프로토콜을 제안할지를 논의했다. 회합은 성황을 이루었고 IETF에서 정식으로 OAuth 작업모임을 발족시키는 일에 폭넓은 지지를 얻을 수 있었다.

2010년 IETF에서 OAuth 1.0 공식 표준안이 RFC 5849로 발표되었다.

역시 우리 개발자들은 불편한걸 개선하고 반복적인 것을 자동화하는 사람들인 것이다!✌ 아 이거 불편하네..?? 아 이거 자꾸 반복하네..?? 하는 것들이 있다면 그것이 개선 포인트이다!

등장 개념

OAuth에서는 아래와 같은 개념이 등장한다.

  • Resource Server : OAuth 서비스를 이용해서 접근을 지원하는 어플리케이션 현재 문맥에서는 소셜 미디어 회사
  • Authorization Server : Resource Server에서 실제 인증 및 인가를 담당하는 것
  • Resource Owner : 서비스를 이용하려는 유저
  • Client : OAuth를 이용해 사용자의 허락을 받아 소셜 미디어의 리소스에 접근하는 어플리케이션

OAuth 기능을 추상화한 Interface

현재 사용되고 있는 OAuth 2.0은 공식 표준화 된 국제 표준이다. 구글이든 카카오든 아래와 같은 기능만 구현하면 소셜 미디어 로그인 기능을 구현할 수 있다. 표준의 위엄..!!! 😍 본인의 개인프로젝트에서 사용한 interface를 보고 어떠한 기능이 필요한지 확인해보자

public interface ISNSLogin
{
    // 설정 정보를 이용해 로그인 요청을 할 수 있는 URI를 만들어 반환한다.
    string GetAuthorizationRequestURI();
    // 설정 정보를 이용해 사용자 로그인 허락에 따른 응답을 받기 위한
    // Redirect URI를 만들고 Redirect URI에서 온 Access Token을 Http header에 설정한다.
    Task<bool> SetAccessTokenAsync(string code);
    // 설정된 Access Token을 이용해서 해당 Social Media에게 사용자의 정보를 얻는다.
    // 이 정보를 이용해 추후에 DB의 값과 비교해 로그인 기능을 수행한다.
    Task<TResponse> GetUserInfoAsync<TResponse>();
}

OAuth 흐름도

간략한 OAuth2.0의 흐름도를 그려보았다. 이해 하기 쉽게 Authorization Server, Resouce Server 개념을 Service Provider에 통합했다. 그리고 핫핑크색으로 위에 보여드린 ISNSLogin interface의 함수들이 언제 호출되는지 표시하였다. 그림을 잘 보면 Client에서 Service Provider로의 호출이 3번 있는 것을 알 수 있다. 이 과정은 OAuth표준으로써 모든 SNS Login 서비스를 이용하는 클라이언트에서 통신을 해야하는 부분으로 이 부분을 추상화하였다. 그림과 설명을 보고 OAuth표준을 글쓴이가 어떤식으로 추상화했는지 확인해보기 바란다.

  1. 사용자가 현재 앱의 SNSLogin 버튼을 눌러 SNS Login 요청을 한다.
  2. 앱에서는 이미 각 SNS Login 가능한 사이트에 등록된 정보를 가지고 SNS Login 창을 띄워주는 URI를 만든다. 이 과정은 모든 SNS Login에서 진행하므로 GetAuthorizationRequestURI()함수로 추상화 하였다.
  3. 승인 페이지를 Service Provider에 요청한다.
  4. Service Provider는 요청받은 SNS Login 창을 회신한다.
  5. 사용자는 승인을 한다.
  6. 승인을 하면 미리 등록 되어있는 Redirection URI로 임시 비밀번호 격인 Code를 전송해준다.
  7. Code를 이용해 AccessToken을 요청한다. 이 과정도 SetAccessToken(code)함수로 추상화 되어있다.
  8. 요청받은 AccessTokenClient에게 전달한다.
  9. AccessToken을 이용해서 유저정보를 요청한다. 이 과정도 GetUserInfoAsync(accessToken)으로 추상화 되어있다.
  10. 미리 설정된 만큼의 유저 정보를 받는다. 대체로 유저의 아이디, email, 프로필 사진 등을 받는다.
  11. 유저의 정보를 가지고 로그인 시도를 한다.
  12. 로그인 완료한다.

글쓴이의 의문

왜? 6번의 과정이 필요한 것인가?

왜? 바로 Access Token을 주지 않는건가?

이것에 대한 정답은 스택 오버플로우(클릭)에서 볼 수 있다. 감히 완벽한 대답이라고 생각한다. OAuth2.0을 표준으로 만들 당시 그들은 세상의 모든 개발자가 유료 인증서를 가지고 HTTPS를 구현하고 있을 것이라고 판단하지 않았다. 만약 보안을 위해 그것을 강제하는 하면 OAuth의 표준으로써의 가치가 상실 될 수 있다고 판단했다. 그래서 통신 중 가로채여도 괜찮은 임시성 Code를 먼저 발급하고 그것을 이용해 AccessToken을 안전하게 Client에게 전달한다. AccessTokenHTTP요청의 일부로써 전송되는 것이 아니라 해시 조각이라는 것으로 전달 된다고 한다. 그래서 전송 중 서버나 라우터에서 이것을 가로챌 수 없으며 2번과정에서 만들어낸 브라우저에서만 이것을 읽을 수 있다. 이로써 안전하게 AccessToken을 전달할 수 있는 것이다.

profile
.NET 개발자 마수리입니다 🖐

0개의 댓글