티스토리 뷰

반응형

daum, naver 등 대형 포탈의 경우 oAuth 인증을 이용한 접근을 이용하면, 개인의 가입된 카페 목록이나 해당 카페의 목록등을 CRUD할 수 있게 된다. 그런데.. naver의 경우 oAuth 인증을 할때 .net 기반은 사용하지 말라고 하는 의지가 좀 보인다. 그래서, 일단 daum의 oAuth를 먼저 작성을 하였다.

1. 참고 자료
OAuth 시작하기
http://dna.daum.net/apis/oauth

danielcrenna / oauth
https://github.com/danielcrenna/oauth

OAuth 초보자 가이드 - Part 3 : 보안 아키텍쳐
http://blog.naver.com/PostView.nhn?blogId=redspider0&logNo=70126973417


2. 핵심만 먼저 이야기를 해보자
oAuth 인증이면 무조건 Header에 인증 관련 데이터를 모두 넣어서 보내주면 된다. 무지 간단한 것인데..그 Header에 넣을 데이터를 구성하는 것이 좀 까다롭다. 그래서 danielcrenna / oauth 이 곳에 있는 dll을 포함해서 작업을 한다. vs2010에서는 NuGet으로 포함 시키면 된다.

Manage NuGet Package for Solution -> oauth로 검색하고, 뒤로 좀 넘어가면 OAuth라는 것이 보인다. 인스톨을 하자.



3. MainPage.xaml.cs

using System;
using System.Linq;
using System.Net;
using System.Text;
using System.Windows;
using Microsoft.Phone.Controls;
using Microsoft.Phone.Tasks;
using OAuth;

//oAuth 관리 객체에 대한 오픈 소스 : https://github.com/danielcrenna/oauth
//NuGet package OAuth로 검색 OAuth, An implementation of OAuth 1.0a for .Net 설치
//핵심 : 각 단계마다 oAuth관리 객체에 필요한 데이터를 넣고 .GetAuthorizationHeader()를 호출해서
//       헤더 정보를 만든 후 request 객체의 해더에 방금 만든 정보를 추가하고 호출
namespace DaumPhoneApp
{
    public partial class MainPage : PhoneApplicationPage
    {
        //daum oAuth : http://dna.daum.net/apis/oauth
        //컨슈머 등록 : https://apis.daum.net/oauth/consumer/input
        //컨슈머 키, 시크릿 - 자신의 키를 입력해야 한다.
        const string consumerKey = "";
        const string consumerSecret = "";

        //url들
        string requestUrl = "https://apis.daum.net/oauth/requestToken";
        string userAuthorizeUrl = "https://apis.daum.net/oauth/authorize";
        string accessUrl = "https://apis.daum.net/oauth/accessToken";
        string callbackUrl = "oob";

        //oAuth관리 객체
        OAuthRequest client;

        // Constructor
        public MainPage()
        {
            InitializeComponent();

            this.Loaded += new RoutedEventHandler(MainPage_Loaded);
        }

        void MainPage_Loaded(object sender, RoutedEventArgs e)
        {
            //oAuth 관리 객체 생성
            client = new OAuthRequest
            {
                Method = "GET",
                ConsumerKey = consumerKey,
                ConsumerSecret = consumerSecret,
                CallbackUrl = callbackUrl,
                SignatureMethod = OAuthSignatureMethod.HmacSha1,
                Realm = "https://apis.daum.net/oauth",
                Version = "1.0"
            };
        }

        //Request Token 받아오기
        private void Button_Click(object sender, RoutedEventArgs e)
        {
            //request token
            client.RequestUrl = requestUrl;
            var auth = client.GetAuthorizationHeader();

            var request = (HttpWebRequest)WebRequest.Create(client.RequestUrl);
            request.Headers["Authorization"] = auth;
            request.BeginGetResponse(new AsyncCallback(callBack), request);
        }

        private void callBack(IAsyncResult asyncResult)
        {
            //결과 처리
            var request = (HttpWebRequest)asyncResult.AsyncState;
            var response = request.EndGetResponse(asyncResult);
            var content = response.GetResponseStream();
            int length = Convert.ToInt32(content.Length);
            byte[] bytes = new byte[length];
            content.Read(bytes, 0, length);

            Encoding enc = Encoding.UTF8;
            string myString = enc.GetString(bytes, 0, length);
            //받아온 토큰을 client에 입력
            var splite = myString.Split('&');
            var token = from kkk in splite
                        let sp = kkk.Split('=')
                        select new { key = sp[0], value = sp[1] };
            client.Token = token.FirstOrDefault(p => p.key == "oauth_token").value;
            client.TokenSecret = token.FirstOrDefault(p => p.key == "oauth_token_secret").value;

            //사용자 인증 페이지 출력
            WebBrowserTask webTask = new WebBrowserTask();
            var uri = new Uri(userAuthorizeUrl + "?oauth_callback=oob&oauth_token=" + client.Token, UriKind.Absolute);
            webTask.Uri = uri;
            webTask.Show();
        }

        private void Button2_Click(object sender, RoutedEventArgs e)
        {
            //사용자 인증 번호 입력 후 accessToken 받기 위해서 다시 호출
            client.RequestUrl = accessUrl;
            client.Verifier = txtVerifier.Text;
            var auth = client.GetAuthorizationHeader();

            var request = (HttpWebRequest)WebRequest.Create(client.RequestUrl);
            request.Headers["Authorization"] = auth;
            request.BeginGetResponse(new AsyncCallback(callBack2), request);
        }

        private void callBack2(IAsyncResult asyncResult)
        {
            //결과 처리
            var request = (HttpWebRequest)asyncResult.AsyncState;
            var response = request.EndGetResponse(asyncResult);
            var content = response.GetResponseStream();
            int length = Convert.ToInt32(content.Length);
            byte[] bytes = new byte[length];
            content.Read(bytes, 0, length);

            Encoding enc = Encoding.UTF8;
            string myString = enc.GetString(bytes, 0, length);
            //accessToken 을 다시 client에 입력
            var splite = myString.Split('&');
            var token = from kkk in splite
                        let sp = kkk.Split('=')
                        select new { key = sp[0], value = sp[1] };
            client.Token = token.FirstOrDefault(p => p.key == "oauth_token").value;
            client.TokenSecret = token.FirstOrDefault(p => p.key == "oauth_token_secret").value;

            //버튼 활성화
            Dispatcher.BeginInvoke(() =>
            {
                btnGetCafeList.IsEnabled = true;
            });
       }

        private void Button3_Click(object sender, RoutedEventArgs e)
        {  
            //카페 목록 조회
            //client.RequestUrl = "http://apis.daum.net/cafe/alimis.xml";
            client.RequestUrl = "http://apis.daum.net/cafe/favorite_cafes.xml";
            var auth = client.GetAuthorizationHeader();
            var request = (HttpWebRequest)WebRequest.Create(client.RequestUrl);
            request.Headers["Authorization"] = auth;
            request.BeginGetResponse(new AsyncCallback(callBack3), request);
        }

        private void callBack3(IAsyncResult asyncResult)
        {
            //결과 처리
            var request = (HttpWebRequest)asyncResult.AsyncState;
            var response = request.EndGetResponse(asyncResult);
            var content = response.GetResponseStream();
            int length = Convert.ToInt32(content.Length);
            byte[] bytes = new byte[length];
            content.Read(bytes, 0, length);

            Encoding enc = Encoding.UTF8;
            string cafeList = enc.GetString(bytes, 0, length);

            //카페 목록 출력
            Dispatcher.BeginInvoke(() =>
            {
                tbList.Text = cafeList;
            });
        }
    }
}

4. 실행
1) 첫 화면 - Request Token 버튼을 클릭해서 토큰을 받고 사용자 인증 페이지로 넘어간다.


2) 사용자 인증 페이지로 이동


3) 로그인 먼저 하고..


4) 아이디 인증 - 확인


5) 인증 번호를 적어서 본 프로그램으로 이동 (pc에서 하면 복사 기능이 되는데.. 윈폰에서는 않됨)


6) 인증 번호를 입력 후 ok 버튼 클릭 -> Get Cafe List 버튼이 활성화 됨

7) 자주가는 카페 목록 조회 성공

5. 소스 정리를 하지 않았다.
이 포스트는 oAuth 인증하는 과정을 알려주기 위해서 있는 그대로의 자연스러움(?)을 유지 하려고 노력했다. 이 셈플 만들기 까지 약 10시간 정도의 시간이 걸린 것 같다. 앞으로는 oAuth가 나와도 겁내지 말고 잘 써보도록 하자.

 

oAuthPhoneApp.zip
다운로드

 

반응형
댓글