2007년 8월
소개: AuthSub가 중요한 이유
Google 데이터 API ('GData'라고도 함)의 장점은 개발자가 Google 서비스와 상호작용하는 애플리케이션을 빌드할 수 있다는 점입니다. 더 구체적으로 말하면 애플리케이션에서 사용할 비공개 사용자 데이터에 액세스할 수 있습니다. API를 사용하면 데이터를 동기화, 가져오기, 내보내기, 관리하는 애플리케이션을 작성할 수 있습니다. API를 통해 이러한 강력한 기능을 사용할 수 있지만 책임감 있게 사용해야 합니다. 사용자 데이터는 개인 정보이므로 안전한 방식으로 액세스해야 합니다. 이러한 작업의 핵심은 안전한 방식으로 Google 서버에 인증할 수 있다는 것입니다.
Google 웹 서비스에 저장된 데이터와 연결하려는 새로운 웹 애플리케이션이 있다고 가정해 보겠습니다. 이제 이 비공개 데이터에 액세스하기 위해 인증을 수행하려고 합니다. ClientLogin과 같은 간단한 것을 사용하면 안 되나요? 이렇게 하면 문제가 해결되지만 사용자 로그인 사용자 인증 정보라는 더 많은 비공개 데이터를 처리해야 합니다. ClientLogin을 사용하려면 애플리케이션에서 사용자의 Google 사용자 이름과 비밀번호를 요청해야 합니다. 이는 사용자의 개인 머신에서 실행되는 데스크톱 애플리케이션에는 적합하지만 웹 기반 애플리케이션에는 적합하지 않습니다. 자체 서버에서 이러한 사용자 인증 정보를 처리해야 하는 책임 외에도 신중한 일부 사용자는 Google에서 자신의 정보를 저장할까 봐 두려워할 수 있습니다. 사용자가 흔히 우려하는 또 다른 사항은 프로그램에 특정 서비스 (예: Google Calendar의 일정)에 대한 액세스 권한만 부여하고 다른 서비스 (예: Google 문서)에 대한 액세스 권한은 부여하지 않으려는 경우입니다. AuthSub는 사용자가 Google 서버를 통해 인증할 수 있도록 하고 프로그램이 필요한 액세스 권한만 요청할 수 있도록 하여 이 두 가지 문제를 모두 해결합니다.
AuthSub의 이론에 대해 충분히 읽었으므로 이제 코딩으로 넘어가 보겠습니다. 이 도움말에서는 간단하게 단일 ASP 페이지 내에서 모든 작업을 수행했지만 여기에 설명된 기법을 자체 애플리케이션에 쉽게 통합할 수 있습니다.
인증 처리
웹 애플리케이션에서 AuthSub를 실제로 사용하려면 무엇이 필요할까요? 먼저 GData 클라이언트 라이브러리에서 가져오는 표준 항목이 있습니다.
<%@ Import Namespace="Google.GData.Client" %> <%@ Import Namespace="Google.GData.Extensions" %> <%@ Import Namespace="System.Net" %>
이제 가장 먼저 해야 할 일은 사용자를 특별히 제작된 URL로 보내는 것입니다. 이를 통해 Google 서버가 인증을 처리한 다음 사용자를 웹사이트로 다시 리디렉션할 수 있습니다. 다행히 이 URL을 수동으로 생성하지 않아도 됩니다. URL을 생성하는 방법이 있기 때문입니다. 예를 살펴보겠습니다.
authSubUrl = AuthSubUtil.getRequestUrl(target, scope, secure, session);
- target 웹 애플리케이션의 URL이 포함된 문자열입니다. 인증 후 사용자가 리디렉션되는 위치입니다.
- scope 이 문자열은 사용 중인 API에 따라 결정됩니다. GData API의 피드 중 하나에 해당합니다. 예를 들어 사용자의 모든 캘린더 정보가 포함된 피드는 'http://www.google.com/calendar/feeds/default/private/full'입니다.
- secure: 서버에 Google에 등록되었으며 서버에 대한 요청에 암호화 서명을 할 것임을 알리는 불리언입니다. 이 인수는 특히 테스트 환경에서 작업할 때 기본적으로 false입니다.
- session: '일회용 토큰'이 아닌 '세션 토큰'을 원하는지 나타내는 또 다른 불리언입니다. 이 인수의 역할은 잠시 후에 더 명확해집니다.
사용자가 생성된 URL을 클릭하면 Google 계정 페이지로 이동하여 Google 계정에 로그인할 수 있습니다. 그런 다음 'target' 변수에 지정된 웹페이지로 다시 리디렉션되지만 일회용 토큰이 포함된 'token' 쿼리 매개변수가 추가됩니다. 일반적으로 이 토큰은 정확히 한 번 사용할 수 있습니다. 즉, 지정된 피드에서 하나의 작업을 실행하는 데 사용할 수 있습니다. 하지만 'session' 매개변수를 true로 지정한 경우 사용자가 세션을 종료할 때까지 재사용할 수 있는 '세션 토큰'으로 교환할 수 있습니다. 다음과 같은 방법으로 이 작업을 수행할 수 있습니다.
String token = Request.QueryString["token"]; Session["token"] = AuthSubUtil.exchangeForSessionToken(token, null).ToString();
여기에서 쿼리 매개변수에서 토큰을 추출하고 '세션 토큰'으로 교환합니다. 그런 다음 나중에 사용할 수 있도록 .NET의 자동 Session
배열에 저장할 수 있습니다. 물론 데이터베이스에 토큰을 저장할 수도 있습니다. 다음 단계는 이 토큰을 사용하여 인증된 요청을 만드는 것입니다.
GAuthSubRequestFactory authFactory = new GAuthSubRequestFactory("cl", "My-Cool-Application"); authFactory.Token = (String) Session["token"]; CalendarService service = new CalendarService(authFactory.ApplicationName); service.RequestFactory = authFactory;
여기에서는 인증을 위해 AuthSub를 사용하여 Google Calendar API와 상호작용하도록 CalendarService 객체를 설정합니다. GAuthSubRequestFactory
생성자에 사용된 'cl'은 Calendar의 서비스 이름입니다. 다른 서비스 이름은 Google Data API FAQ를 참고하세요.
보안 (등록된) AuthSub
웹 애플리케이션을 등록하면 AuthSub를 사용하는 동안 추가 보안 수준을 사용 설정할 수 있습니다. 이렇게 하면 코드에서 이루어진 모든 요청에 디지털 서명을 할 수 있으므로 비공개 키가 없는 사용자는 개발자에게 발급된 AuthSub 토큰을 사용할 수 없습니다. 첫 번째 단계는 'secure' 인수를 true로 설정하여 AuthSubUtil.getRequestUrl
를 호출할 때 올바른 AuthSub 링크를 생성하는 것입니다. 다음 두 가지 코드를 변경해야 합니다.
String token = Request.QueryString["token"]; Session["token"] = AuthSubUtil.exchangeForSessionToken(token, rsaKey).ToString(); ... authFactory.PrivateKey = rsaKey;
먼저 null
대신 변수 'rsaKey'를 exchangeForSessionToken
메서드에 전달합니다. 이 동일한 변수는 서비스에 대한 연결을 설정할 때 GAuthSubRequestFactory
의 속성을 설정하는 데도 사용됩니다. 'rsaKey' 변수는 Google에 등록한 x509 인증서의 비공개 키 구성요소에 해당하는 RSACryptoServiceProvider
입니다.
RSA 비공개 키와 자체 서명 인증서를 생성하는 것은 약간 혼란스러울 수 있습니다. 특히 .NET 프레임워크에서는 PEM 형식으로 저장된 키나 인증서를 이해하지 못하기 때문입니다. 다음 명령어는 OpenSSL 도구 모음을 사용하여 비공개 키와 공개 인증서를 생성하는 방법을 보여줍니다.
openssl req -x509 -nodes -days 365 -newkey rsa:1024 -sha1 -subj \ '/C=US/ST=CA/L=Mountain View/CN=www.example.com' -keyout \ test_key.pem -out test_cert.pem openssl pkcs12 -export -in test_cert.pem -inkey test_key.pem \ -out test_cert.pfx -name "Testing Certificate"
첫 번째 단계에서는 각각 'test_key.pem' 및 'test_cert.pem'이라는 PEM 형식의 비공개 키와 공개 X509 인증서를 생성합니다. 인증서가 미국 캘리포니아주 마운틴뷰에 있는 'www.example.com'에 등록되도록 설정되어 있습니다. 여기에 회사에 적합한 값을 입력하세요. 'test_cert.pem' 파일에는 AuthSub 등록 페이지에 제출해야 하는 정보가 포함되어 있습니다.
두 번째 단계에서는 비공개 키와 인증서에서 PFX 파일을 생성합니다. 이 파일은 GData API에 대한 요청을 디지털 서명하기 위해 .NET 클라이언트 라이브러리로 가져올 수 있습니다. 다음 코드는 PFX 파일에서 웹 애플리케이션으로 비공개 키를 가져오는 방법을 보여줍니다.
protected AsymmetricAlgorithm getRsaKey() { X509Certificate2 cert = new X509Certificate2("C:/MyAspSite/test_cert.pfx",""); RSACryptoServiceProvider privateKey = cert.PrivateKey as RSACryptoServiceProvider; return privateKey; }
이 스니펫으로 정의된 getRsaKey()
함수는 API를 인증하는 데 사용될 때 위에 표시된 'rsaKey' 변수 대신 사용할 수 있습니다. 당연히 파일 경로는 생성한 PFX 파일의 적절한 위치로 대체해야 합니다.
전체 코드 목록
이전 섹션에 설명된 메서드를 사용하는 방법을 보여주는 가장 쉬운 방법은 실제 예시를 사용하는 것입니다. 다음 샘플 코드는 AuthSub를 사용하여 사용자를 인증한 다음 Google Calendar의 일정을 출력하는 간단한 ASP 페이지입니다.
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" %> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <%@ Import Namespace="Google.GData.Client" %> <%@ Import Namespace="Google.GData.Extensions" %> <%@ Import Namespace="Google.GData.Calendar" %> <%@ Import Namespace="System.Net" %> <script runat="server"> void PrintCalendar() { GAuthSubRequestFactory authFactory = new GAuthSubRequestFactory("cl", "TesterApp"); authFactory.Token = (String) Session["token"]; CalendarService service = new CalendarService(authFactory.ApplicationName); service.RequestFactory = authFactory; EventQuery query = new EventQuery(); query.Uri = new Uri("http://www.google.com/calendar/feeds/default/private/full"); try { EventFeed calFeed = service.Query(query); foreach (Google.GData.Calendar.EventEntry entry in calFeed.Entries) { Response.Write("Event: " + entry.Title.Text + "<br/>"); } } catch (GDataRequestException gdre) { HttpWebResponse response = (HttpWebResponse)gdre.Response; //bad auth token, clear session and refresh the page if (response.StatusCode == HttpStatusCode.Unauthorized) { Session.Clear(); Response.Redirect(Request.Url.AbsolutePath, true); } else { Response.Write("Error processing request: " + gdre.ToString()); } } } </script> <html xmlns="http://www.w3.org/1999/xhtml" > <head runat="server"> <title>Test Site</title> </head> <body> <form id="form1" runat="server"> <h1>AuthSub Sample Page</h1> <div> <% GotoAuthSubLink.Visible = false; if (Session["token"] != null) { PrintCalendar(); } else if (Request.QueryString["token"] != null) { String token = Request.QueryString["token"]; Session["token"] = AuthSubUtil.exchangeForSessionToken(token, null).ToString(); Response.Redirect(Request.Url.AbsolutePath, true); } else //no auth data, print link { GotoAuthSubLink.Text = "Login to your Google Account"; GotoAuthSubLink.Visible = true; GotoAuthSubLink.NavigateUrl = AuthSubUtil.getRequestUrl(Request.Url.ToString(), "http://www.google.com/calendar/feeds/",false,true); } %> <asp:HyperLink ID="GotoAuthSubLink" runat="server"/> </div> </form> </body> </html>
결론
AuthSub를 사용하면 웹 애플리케이션이 사용자의 Google 계정에 저장된 데이터에 안전하고 제어된 방식으로 액세스할 수 있습니다. .NET 클라이언트 라이브러리를 사용하면 ASP 기반 웹사이트를 Google 서비스와 쉽게 통합할 수 있습니다. 이 도움말은 시작하는 데 도움이 되도록 작성되었으며, 다음과 같은 추가 리소스를 참고하는 것이 좋습니다.