흔히 말하는 SNS Login기능은 국제표준으로 자리잡은 OAuth2.0
기술을 따라 진행되게 되어있다. OAuth
를 알아보면서 개인프로젝트를 하면서 SNS Login 기능을 개발했던 내용을 다루어본다. 시작하자!🚀
Google Login Source Code
GoogleLoginProvider
KakaoTalk Login Source Code
KakaoLoginProvider
요즘 시대의 우리는 아래와 같은 로그인 화면에서 다양한 소셜 미디어를 이용한 로그인 기능을 당연시 생각하는 사회에 살고 있다. 아래 사진에서 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
에서는 아래와 같은 개념이 등장한다.
OAuth
서비스를 이용해서 접근을 지원하는 어플리케이션 현재 문맥에서는 소셜 미디어 회사Resource Server
에서 실제 인증 및 인가를 담당하는 것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
표준을 글쓴이가 어떤식으로 추상화했는지 확인해보기 바란다.
GetAuthorizationRequestURI()
함수로 추상화 하였다.Service Provider
에 요청한다.Service Provider
는 요청받은 SNS Login 창을 회신한다.Redirection URI
로 임시 비밀번호 격인 Code
를 전송해준다.Code
를 이용해 AccessToken
을 요청한다. 이 과정도 SetAccessToken(code)
함수로 추상화 되어있다.AccessToken
을 Client
에게 전달한다.AccessToken
을 이용해서 유저정보를 요청한다. 이 과정도 GetUserInfoAsync(accessToken)
으로 추상화 되어있다.왜?
6번
의 과정이 필요한 것인가?
왜? 바로
Access Token
을 주지 않는건가?
이것에 대한 정답은 스택 오버플로우(클릭)에서 볼 수 있다. 감히 완벽한 대답이라고 생각한다. OAuth2.0
을 표준으로 만들 당시 그들은 세상의 모든 개발자가 유료 인증서를 가지고 HTTPS
를 구현하고 있을 것이라고 판단하지 않았다. 만약 보안을 위해 그것을 강제하는 하면 OAuth
의 표준으로써의 가치가 상실 될 수 있다고 판단했다. 그래서 통신 중 가로채여도 괜찮은 임시성 Code
를 먼저 발급하고 그것을 이용해 AccessToken
을 안전하게 Client
에게 전달한다. AccessToken
은 HTTP
요청의 일부로써 전송되는 것이 아니라 해시 조각
이라는 것으로 전달 된다고 한다. 그래서 전송 중 서버나 라우터에서 이것을 가로챌 수 없으며 2번
과정에서 만들어낸 브라우저에서만 이것을 읽을 수 있다. 이로써 안전하게 AccessToken
을 전달할 수 있는 것이다.