일단 인증을 받기 위해서 애플리케이션을 등록해야합니다.
페이스북 developer페이지
http://www.facebook.com/#!/developers/apps.php

여기서 새 애플리케이션 셋업을 선택해서 애플리케이션을 등록해야합니다.
등록하고 나서 설정에서 Web Site탭에서
Site URL을 해당 "http://인증할 사이트주소/", Site Domain을 "인증할 사이트주소" 이렇게 설정합니다. 이렇게 안하니까 에러나더라구요-_-
저는 http://mudchobo.tomeii.com/ , mudchobo.tomeii.com 이렇게 셋팅했습니다.

그리고 이제 인증받을 페이지를 만듭니다.
index.html
[code]
<!DOCTYPE html>
<html>
    <head>
        <script type="text/javascript" src="/js/jquery-1.4.2.min.js"></script> 
        <script type="text/javascript">
            $(document).ready(function(){
                $("#btnAuth").click(function(){
                    window.location = "https://graph.facebook.com/oauth/authorize?client_id=126292714090241&redirect_uri=http://mudchobo.tomeii.com/test/facebook/callback.html&type=user_agent&display=popup&scope=publish_stream,create_event,rsvp_event,sms,offline_access";
                });
            });
        </script>
    </head>
    <body>
        <button type="button" id="btnAuth" name="btnAuth">인증받기</button>
    </body>
</html>
[/code]
뭐 간단한데, 인증버튼이 있는데, 인증 받으려고 해당 url로 갑니다. 이거 팝업으로 한다음에 인증받고 callback에서 다시 팝업->부모페이지로 전달해서 하는 방법도 있는데, 귀찮으니까 그냥 페이지로 넘기고 콜백으로 넘어갑시다-_-

인증url을 보면 client_id가 application_id입니다. 저는 이런 단어통일이 안되어서 몬가 삽질을 좀 했습니다. 왜 단어가 틀려-_-

그리고 rediret_uri는 인증받고 다시 돌아올 주소고, scope는 이 인증에 어디까지 권한을 주는것이냐 입니다. 저기에 있는 게 다인데, 글쓰기권한은 publish_stream하나면 되는 듯. 나머지는 몰라서 막 추가해봤음...ㅠㅠ

인증받으려고 하면 아래와 같은 화면이 뜹니다.
사용자 삽입 이미지
허가하기 누르면 이제 access_token을 가지고 callback url로 옵니다.
이제 이 access_token만 있으면 글쓰기를 하거나, 글을 가져올 수 있습니다.

콜백을 보면...
callback.html
[code]
<!DOCTYPE html>
<html>
    <head>
        <script type="text/javascript" src="/js/jquery-1.4.2.min.js"></script> 
        <script type="text/javascript">
            var url;
            var accessToken;
            var userId;
           
            $(document).ready(function(){
                url = new String(window.location);
                accessToken = url.substring(url.indexOf("#") + 14, url.indexOf("&"));
                var userId = accessToken.substring(43, 53);
               
                // 자신의 정보 가져오기
                $.getJSON("https://graph.facebook.com/me?access_token=" + accessToken + "&callback=?", result);
            });
           
            function result(data){
                userId = data.id;
               
                // 글쓰기 버튼 이벤트 추가
                $("#btnWrite").click(function(){
                    var data = $("#taWall").val();
                    if (data.length <= 0){
                        alert("글을 입력하세요!");
                        return;
                    }
                    var query = "use 'http://mudchobo.tomeii.com/test/facebook/facebook_wall_table.xml' as htmlpost;" +
                                    "select * from htmlpost where " +
                                    "url='https://graph.facebook.com/" + userId + "/feed' " +
                                    "and postdata='access_token=" + accessToken + "&message=" + encodeURIComponent(data) +"'" +
                                    "and xpath='//p'";
                    var url = "http://query.yahooapis.com/v1/public/yql?format=json&callback=?&q=" +
                        encodeURIComponent(query) + "&diagnostics=true";
                    $.getJSON(url, cbResult);
                });
            }
           
            function cbResult(data){
                alert("글쓰기 완료!" + data.query.results.postresult.p);
            }
        </script>
    </head>
    <body>
        <textarea id="taWall" name="taWall"></textarea>
        <button id="btnWrite" name="btnWrite">글쓰기</button>
    </body>
</html>
[/code]
accessToken을 url에서 가져오고, 자신의 정보를 access_token을 이용해서 가져옵니다.

그리고, 이제 문제는 글쓰기 부분인데요. 타도메인에 post요청을 할 수 없기 때문에 서버프록시를 이용해야합니다. 제가 가지고 있는 이 tomeii서버는 몬가 https를 요청하니 에러를 뿜는 것 같아-_- YQL이라는 것을 찾았습니다.
이거 좀 짱인데, 나중에 공부해봐야겠습니다.

일단 YQL에 포스트를 날릴 TABLE을 만들어야 하네요. YQL은 저도 잘 모르니 POST요청하는 거 그냥 찾아서 따라해봅니다-_- 아래 사이트 참조
http://www.wait-till-i.com/2009/11/16/using-yql-to-read-html-from-a-document-that-requires-post-data/

facebook_wall_table.xml
[code]
<table xmlns="http://query.yahooapis.com/v1/schema/table.xsd">
    <meta>
        <author>Mudchobo</author>
          <description>HTML pages that need post data</description>
          <sampleQuery>
              <![CDATA[
                select * from {table} where
                url='http://mudchobo.tomeii.com/test/facebook/test.php'
                and postdata="access_token=a&message=b" and xpath="//p"
            ]]>
        </sampleQuery>
          <documentationURL></documentationURL>
      </meta>
      <bindings>
        <select itemPath="" produces="XML">
            <urls>
                  <url>{url}</url>
            </urls>
            <inputs>
                  <key id="url" type="xs:string" required="true" paramType="variable"/>
                  <key id="postdata" type="xs:string" required="true" paramType="variable"/>
                <key id="xpath" type="xs:string" required="true" paramType="variable"/>
            </inputs>
            <execute>
                <![CDATA[
                      var myRequest = y.rest(url);
                      var data = myRequest.accept("text/html")
                        .contentType("application/x-www-form-urlencoded")
                        .post(postdata).response;
                    var xdata = y.xpath(data,xpath);
                    response.object = <postresult>{xdata}</postresult>;
                ]]>
            </execute>
        </select>
      </bindings>
</table>
[/code]
뭐 잘은 모르겠지만, inputs태그에서 postdata랑 url을 받고 여기서 처리를 하는 듯.
javascript같은게 있는데, 여기서 post어쩌구 함수를 호출해서 날리고 response객체 저장시켜놓으면 그걸 얻어올 수 있는 것 같음.

쿼리는 이렇게 날리네요.
[code]
use 'http://mudchobo.tomeii.com/test/facebook/facebook_wall_table.xml' as htmlpost;
select * from htmlpost where url='https://graph.facebook.com/자기페이스북아이디/feed' and postdata='access_token=access_token&message=메세지'and xpath='//p'
[/code]
저렇게 yql을 getJSON으로 날리면 데이터처리를 야후서버에서 하겠죠^^ 그리고 리턴값은 글을 작선한 뒤에 아이디를 받아옵니다.

ps1. YQL진짜 신기하네요-_- 저런식으로 하면 정의된 테이블에 의해서 처리를 한다음에 결과값을 실어서 주네요.

ps2. 예제주소는 여기에....
http://mudchobo.tomeii.com/test/facebook/

 
Posted by 머드초보

댓글을 달아 주세요

  1. 궁금.... 2010.11.29 17:22  댓글주소  수정/삭제  댓글쓰기

    안녕하세요.. 저도 페이스북 연동을 공부하고 있는데요.
    oauth/authorize -> 이후엔 저는 url 을 넘기면 code 값이 넘어오는데
    왜 님 url 은 #access_token 값이 바로 넘어올까요?
    어플 설정때 다른부분이 있었을까요?

  2. BlogIcon 함멸 2010.12.06 23:36 신고  댓글주소  수정/삭제  댓글쓰기

    구독자 1인

  3. 송사마 2011.05.03 11:40  댓글주소  수정/삭제  댓글쓰기

    잘 보고있습니다. 혹씨 허가하기 후에 자동 허가한 대상 담벼락에 글 쓰기가 가능하던데 혹씨 어떤 방식인지 아시는지요? 혹씨 아시면 조언좀 부탁드려요~

  4. 뻬레랑 2011.12.20 11:13  댓글주소  수정/삭제  댓글쓰기

    안녕하세요~ 정보감사합니다~
    혹시..
    위의 소스에서 콜백후에

    아이디/이름/이메일/생년월일/고유ID값 을
    jsp
    화면에 뿌려주려면 어떻게 해야 할지 도움좀 받아도 될까요;;?ㅠㅠ
    혹시나 아시면 답변좀 부탁드려요

  5. BlogIcon sdfgfg 2012.04.02 01:02  댓글주소  수정/삭제  댓글쓰기

    dsfgdsfgdsfg

  6. BlogIcon 질문~! 2012.11.04 15:59  댓글주소  수정/삭제  댓글쓰기

    xml 에서 'http://mudchobo.tomeii.com/test/facebook/test.php' 는 갑자기 어디서
    튀어나온건가요?ㅠ
    잘 따라하다가, 글올리는거에서 막히네요.

 
미투데이도 얼른 OAuth기반으로 바꿨으면 좋겠네요.
인증 방식은 비슷하긴 하지만, access_token요청하는 부분 같은 게 없어서 callbackurl로 사용자api키를 받게 되는군요. 보안상 안좋을 것 같은...-_-

그리고, 언제까지 스프링노트에 표시를 할 것인지가 의문입니다.
트위터가 OpenAPI를 참 잘해놔서 그런지 굉장히 많은 서비스들이 튀어나오고 있습니다. 이점은 미투데이에서도 얼른 OpenAPI에 힘을 쓰시는 게...^^

api페이지입니다.
http://codian.springnote.com/pages/86001

요청절차는 이러합니다. 물론 여기가면 더 자세히 나와있습니다ㅠㅠ(웹인증기반 기준!)
http://codian.springnote.com/pages/1645274
1) api키를 발급받습니다.
2) 해당 api키로 인증 토큰을 얻습니다.
3) 그 토큰으로 인증url로 이동시킵니다.
4)사용자가 로그인 하면 지정한 callback페이지로 사용자키를 던져줍니다.
5) 사용자키로 글을 쓰면 됩니다.


1. 일단 API키 발급

http://me2day.net/me2/app/key/list
여기서 새 애플리케이션 키 발급한다음에 등록합니다. 그리고 등록된 키에서 설정을 누르면 웹기반인지 데스크탑기반인지 선택하는데, 웹기반이면 callback주소를 입력받습니다. 이 callback주소는 인증 후에 사용자키를 받는 url이 됩니다.

2. 해당api키로 인증토큰 얻기
config.php파일
[code]<?php
define('A_KEY', '발급받은 api키');
?>[/code]
index.php
[code]<?php
    require_once("config.php");
    $result = json_decode(file_get_contents("http://me2day.net/api/get_auth_url.json?akey=" . A_KEY));
    print_r($result);
?>
<!doctype html>
<html>
    <head>
        <meta charset="EUC-KR">
        <title>미투데이 인증 후 글쓰기</title>
      </head>
    <body>
        <br />
        <a href="<?php echo $result->url ?>">미투데이 인증하기</a>
      </body>
</html>[/code]
php에서 http://me2day.net/api/get_auth_url.json를 요청해서 token을 받습니다. 그러면 인증url이 같이 떨어집니다. 그 url로 이동하게 되면 아래와같이 로그인하는 화면이 나옵니다.
사용자 삽입 이미지
여기서 로그인하고 인증하면 1번에서 지정한 callbackurl로 이동하게 됩니다.

3. callback url에서 데이터받고 글쓰기 폼생성

callback.php
[code]<?php
    require_once("config.php");
   
    $token = $_GET["token"];
    $user_id = $_GET["user_id"];
    $user_key = $_GET["user_key"];
    $result = $_GET["result"];
   
    // 세션저장
    session_start();
    $_SESSION["user_id"] = $user_id;
    $_SESSION["user_key"] = $user_key;
   
    // 인증이 확실한지 확인
    $authKey = "12345678" . md5("12345678" . $user_key);
    $result = file_get_contents("http://me2day.net/api/noop?uid={$user_id}&ukey={$authKey}&akey=" . A_KEY);
?>
<!doctype html>
<html>
    <head>
        <meta charset="EUC-KR">
        <title>미투데이 인증 콜백</title>
        <script type="text/javascript" src="/js/jquery-1.4.2.min.js"></script>
        <script type="text/javascript">
            $(document).ready(function(){
                $("#btnPost").click(function(){
                    var body = $("#inputPost").val();
                    if (body.length < 1){
                        alert("글입력해요!");
                        return;
                    }
                    $.getJSON("post.php?callback=?", {body:body}, function(data){
                        alert("글쓰기 성공 = " + data.result);
                    });
                });
            });
        </script>
      </head>
    <body>
        <?php echo $result ?><br/>
        <input type="text" id="inputPost" name="inputPost" /><br />
        <input type="button" id="btnPost" name="btnPost" value="글쓰기"/>
      </body>
</html>[/code]
보면 user_id랑 user_key를 세션에 저장합니다. 만약 자신의 사이트에서 미투데이인증과 통합을 원한다면 api키를 데이터베이스같은 영속적인 것에 저장하고 쓰는 것이 좋습니다. 그럼 따로 인증같은 것을 하지 않아도, 자신의 사이트만 인증을 해도 글을 쓸 수 있으니까요^^
나중에 api_key값이 바뀐다고 해도, noopapi를 호출해서 인증이 정확한지 확인 후 정확하지 않으면 다시 인증받으면 되니까요^^

user_id랑 user_key만 있으면 이제 글을 쓸 수 있으므로, http://me2day.net/api/noop를 호출해서 유효한지 확인을 합니다. 이제부터 인증받은 api들은 uid와 ukey와 akey를 같이 파라메터에 붙여서 호출해야합니다.
uid는 사용자 아이디, ukey는 임의8자리숫자 + md5(임의8자리숫자 + 사용자키), akey는 api키를 넣으면 됨!

4. 글쓰기
post.php
[code]<?php
    require_once("config.php");
   
    $body = $_GET["body"];
    $callback = $_GET["callback"];
   
    session_start();
    $user_id = $_SESSION["user_id"];
    $user_key = $_SESSION["user_key"];
   
   
    // 인증이 확실한지 확인
    $authKey = "12345678" . md5("12345678" . $user_key);
    $result = file_get_contents("http://me2day.net/api/create_post/{$user_id}.json?uid={$user_id}&ukey={$authKey}&akey=" . A_KEY . "&post[body]={$body}");
   
    header("Content-type: application/json");
    echo "{$callback}({'result':'{$result}'})";
?>[/code]
그냥 api문서대로 호출하면 됨!

테스트 url~
mudchobo.tomeii.com/test/me2daytest/

나중에 php용 라이브러리를 만들어봐야겠다...
 
Posted by 머드초보

댓글을 달아 주세요

  1. 신최고 2010.07.13 16:15  댓글주소  수정/삭제  댓글쓰기

    글 잘 보았습니다. 헌데 궁금한 점이 있습니다.

    미투데이 사용자 인증을 통해 글쓰기?를 처리하는 이유가 있나요?

    이와 연동하여 사용햇을 경우, 무슨 장점이 있는지 전혀 이해가 가질 않네요;; 휴;;

    • 머드초보 2010.07.21 21:07  댓글주소  수정/삭제

      안녕하세요~
      연동을 하게 되면 자신의 사이트에 미투데이글쓰기를 녹일 수 있지요.
      매쉬업이라고 하는데, 자기가 맛집 사이트를 만들었는데, 거기 댓글을 미투데이로 전송하고 싶으면 오픈api를 이용해서 연동해서 쓸 수 있죠^^

  2. 2011.01.19 17:27  댓글주소  수정/삭제  댓글쓰기

    비밀댓글입니다

  3. BlogIcon 지연 2011.08.02 22:45  댓글주소  수정/삭제  댓글쓰기

    내친구할래

  4. BlogIcon 지연 2011.08.02 22:45  댓글주소  수정/삭제  댓글쓰기

    내친구할래

  5. BlogIcon 지연 2011.08.02 22:45  댓글주소  수정/삭제  댓글쓰기

    내친구할래

  6. BlogIcon 지연 2011.08.02 22:45  댓글주소  수정/삭제  댓글쓰기

    내친구할래

  7. BlogIcon 이영석 2013.01.11 10:25  댓글주소  수정/삭제  댓글쓰기

    정말 잘봤습니다. 안그래도 이걸 찾고있었는데 ㅍ.ㅍ 감사합니다.

 
두번째글입니다.
프로그램 설치 및 체험(?)은 아래의 INSTALL NOW을 클릭해주세요 ^^

Alternative content

Get Adobe Flash player


이제 air프로젝트를 하나 생성합니다.
[code]
<?xml version="1.0" encoding="utf-8"?>
<mx:WindowedApplication xmlns:mx="http://www.adobe.com/2006/mxml"
    layout="vertical" width="300" height="300"
    horizontalAlign="center" verticalAlign="middle"
    verticalScrollPolicy="off" horizontalScrollPolicy="off">
   
    <mx:Script>
        <![CDATA[
            import flash.net.navigateToURL;
            import mx.rpc.events.FaultEvent;
            import mx.controls.Alert;
            import mx.rpc.events.ResultEvent;
            import com.mudchobo.MudchoboOAuth;
           
            private var mudchoboOAuth:MudchoboOAuth;
            private var consumerToken:String = "자신의 Consumer Token";
            private var consumerSecret:String = "자신의 Consumer Secret";
            private var requestTokenURL:String = "http://www.storyq.net/oauth/request_token";
            private var accesstokenURL:String = "http://www.storyq.net/oauth/access_token";
            private var authorizeURL:String = "http://www.storyq.net/oauth/authorize";
           
            private function login():void
            {
                // RequestToken 요청
                mudchoboOAuth = new MudchoboOAuth(consumerToken, consumerSecret);
                mudchoboOAuth.requestOAuth(new Object(), requestTokenURL, "POST",
                    requestTokenResultHandler, requestTokenFaultHandler);
                currentState = "stateRequestToken";
            }
           
            private function logout():void
            {
                mudchoboOAuth = null;
                currentState = "";   
            }
           
            private function loginConfirm():void
            {
                // AccessToken요청
                mudchoboOAuth.requestOAuth(new Object(), accesstokenURL, "POST",
                    accessTokenResultHandler, accessTokenFaultHandler);
            }
           
            private function loginCancel():void
            {
                Alert.show("로그인에 실패했습니다.");   
                currentState = "stateStart";
            }
           
            // RequestToken 요청 성공 시
            private function requestTokenResultHandler(event:ResultEvent):void
            {
                currentState = "stateLogin";
                mudchoboOAuth.parseData(event.result.toString());
                authorizeHTML.location = mudchoboOAuth.authorizeSite(authorizeURL);
            }
           
            // RequestToken 요청 실패 시
            private function requestTokenFaultHandler(event:FaultEvent):void
            {
                Alert.show(event.fault.toString() + "요청이 잘못 되었습니다.");
                currentState = "stateStart";
            }
           
            // AccessToken 요청 성공 시
            private function accessTokenResultHandler(event:ResultEvent):void
            {
                currentState = "stateShowMyQ";
                mudchoboOAuth.parseData(event.result.toString());
               
                // 스토리큐에서 자신의 큐리스트를 가져온다.
                mudchoboOAuth.requestOAuth(new Object(), "http://www.storyq.net/boxes/mine.xml", "GET",
                    getQResultHandler, getQFaultHandler);
            }
           
            // AccessToken 요청 실패 시
            private function accessTokenFaultHandler(event:FaultEvent):void
            {
                Alert.show(event.fault.toString() + "요청이 잘못 되었습니다.");
                currentState = "stateStart";
            }
           
            // 자신의 큐리스트 가져오기 요청 성공 시
            private function getQResultHandler(event:ResultEvent):void
            {
                dgQ.dataProvider = event.result.boxes.box;
            }
           
            // 자신의 큐리스트 가져오기 요청 실패 시
            private function getQFaultHandler(event:FaultEvent):void
            {
                Alert.show(event.fault.toString() + "가져오는 도중 실패했습니다.");
            }
           
            // 버튼으로 다시 요청하기
            private function clickReplyHandler():void
            {
                mudchoboOAuth.requestOAuth(new Object(), "http://www.storyq.net/boxes/mine.xml", "GET",
                    getQResultHandler, getQFaultHandler);
            }
           
            // 더블클릭 시 해당 큐로 이동
            private function doubleClickDgQ():void
            {
                if (dgQ.selectedItem.uri != null)
                {
                    navigateToURL(new URLRequest(dgQ.selectedItem.uri), "_blank");
                }   
            }
        ]]>
    </mx:Script>
   
    <mx:states>
        <mx:State name="stateStart">
            <mx:SetProperty name="width" value="300"/>
            <mx:SetProperty name="height" value="300"/>
        </mx:State>
       
        <mx:State name="stateRequestToken">
            <mx:AddChild position="lastChild">
                <mx:Label text="잠시만 기다려주세요..."/>
            </mx:AddChild>
            <mx:SetProperty target="{btnLogin}" name="enabled" value="false"/>
        </mx:State>
       
        <mx:State name="stateLogin">
            <mx:SetProperty name="width" value="1024"/>
            <mx:SetProperty name="height" value="768"/>
            <mx:AddChild position="lastChild">
                <mx:HTML width="1024" height="642" id="authorizeHTML"/>
            </mx:AddChild>
            <mx:RemoveChild target="{btnLogin}"/>
            <mx:AddChild relativeTo="{authorizeHTML}" position="before">
                <mx:HBox id="hbox1">
                    <mx:Button label="확인" click="loginConfirm()"/>
                    <mx:Button label="취소" click="loginCancel()"/>
                </mx:HBox>
            </mx:AddChild>
            <mx:AddChild relativeTo="{hbox1}" position="before">
                <mx:Text text="아래 창에서 StoryQ사이트 로그인페이지로 이동합니다. &#xa;로그인 완료 후, 확인 버튼을 클릭하주세요." height="40"/>
            </mx:AddChild>
        </mx:State>
       
        <mx:State name="stateShowMyQ">
            <mx:RemoveChild target="{btnLogin}"/>
            <mx:AddChild position="lastChild">
                <mx:Button label="로그아웃" id="btnLogout" click="logout()"/>
                <mx:Button label="다시 가져오기" id="btnReply" click="clickReplyHandler()"/>
            </mx:AddChild>
            <mx:SetProperty name="width" value="550"/>
            <mx:SetProperty name="height" value="422"/>
            <mx:AddChild position="lastChild">
                <mx:DataGrid width="522" height="328" id="dgQ"
                    doubleClickEnabled="true" doubleClick="doubleClickDgQ()">
                    <mx:columns>
                        <mx:DataGridColumn headerText="제목" dataField="title"/>
                        <mx:DataGridColumn headerText="주소" dataField="uri"/>
                    </mx:columns>
                </mx:DataGrid>
            </mx:AddChild>
        </mx:State>
       
    </mx:states>
    <mx:Button label="스토리큐에 로그인" id="btnLogin" click="login()"/>
   
</mx:WindowedApplication>
[/code]
대충만들어서 코드가 지저분합니다만-_-;
아마 알아보실 수 있을듯(응?-_-)합니다.

프로그램을 실행하면, 로그인버튼이 있는데, 로그인 버튼을 클릭하면, 위에서 말한 RequestToken절차가 실행됩니다. RequestToken을 얻어오게 되면, AIR프로그램은 자신의 브라우저를 하나 열어서 로그인 RequestToken을 파라미터로 한 Authorize사이트로 이동합니다.
여기서 사용자는 자신의 아이디로 로그인을 합니다. 로그인이 완료되면, 서버쪽에서 AccessToken을 만들어놓습니다.
로그인 후 위에 확인버튼을 클릭하게 되면, 클라이언트에서는 AccessToken절차가 시작됩니다. AccessToken을 가져온 뒤 그 해당 AccessToken을 이용해 보호된 자원에 접근하는 과정입니다.

접근해서 가져온 데이터는 자신의 큐리스트를 보여주는 겁니다.
자신의 큐들을 데이터그리드에 넣었으며, 그 데이터그리드의 해당 칼럼을 더블클릭하게 되면 해당 큐로 이동하게 됩니다. 정말 별거없네-_-;

위에 코드는 위와 같은 절차로 되어있습니다.
혹시...Oauth로 삽질하시는 분은 이 글로 도움이 되었으면 하네요 ^^

이전 글 링크 - http://mudchobo.tomeii.com/tt/323
PS. 이 짓으로 추석을 날렸습니다-_-;
 
Posted by 머드초보

댓글을 달아 주세요

  1. BlogIcon aproxacs 2008.09.17 15:54  댓글주소  수정/삭제  댓글쓰기

    안녕하세요~
    AIR로 만드셨네요^^. 와우~ 저도 함 배워봐야겠어요~
    ^^

    • 머드초보 2008.09.17 16:39  댓글주소  수정/삭제

      앗~ aproxacs님 반가워요~ ^^
      AIR는 데스크탑애플리케이션 제작하는데 매우 쉽게 할 수 있어요^^

      그나저나 스토리큐는 정말 대단한 것 같아요 ^^
      근데 궁금한게 있는데요. aproxacs는 어떻게 읽어요?-_-;

  2. BlogIcon aproxacs 2008.09.17 16:52  댓글주소  수정/삭제  댓글쓰기

    스토리큐에 종종 놀러 오세요. ㅎㅎ
    저는 '아프락삭스'라고 읽어요^^;

    • 머드초보 2008.09.17 17:11  댓글주소  수정/삭제

      아......그렇게 읽는구나....
      아네 스토리큐에 자주 놀러갈께요 ^^
      스토리큐도 리뷰한번해야겠네요 ^^
      방명록에 글도 남겼어요 ^^

  3. BlogIcon 쿠로 2008.12.25 18:24  댓글주소  수정/삭제  댓글쓰기

    html페이지를 띄워 인증한다음 그데이터를 AIR에서 사용하는것으로 보이는데(AIR Html페이지를 띄우는건 지원하지만).. 그냥 100% Flash와 Actionscript로는 힘들듯보이는데요. 제가생각하는것이 맞는지 궁금하네요.

    • 머드초보 2008.12.26 22:40  댓글주소  수정/삭제

      아넵! 인증은 꼭 브라우저에서 해야합니다.
      OAuth인증방식은 request토큰을 받으면 그것으로 인증페이지를 연다음에 로그인을 합니다.
      그러면 서버에는 accessToken이 생성되는데, 그것을 가져와서 그것을 이용해서 보호된 자원에 접근하는 방식입니다^^
      로그인은 꼭 브라우저에서 해야하는 것입니다^^

  4. BlogIcon 들고양이 2009.06.03 18:35  댓글주소  수정/삭제  댓글쓰기

    리스트 가져올 때 RPC Fault faultString="Http request error" faultCode="Server.Error.Request" faultDetail="Error:[IOErrorEvent type="opError" bubbles=false cancelable=false eventPhase=2 text="Error #2032" errorID=2032]. URL:http://www.stroyq/boxes/mine.xml"] 가져오는도중실패했습니다.

    라고뜨는데 왜그럴까요? 알려주세요^_^;

    • 머드초보 2009.06.05 09:31  댓글주소  수정/삭제

      안녕하세요~
      왜그런지는 모르겠는데, URL에서 www.storyq라고만 되어있네요.
      뭔가 주소를 잘못 입력한 것 같아요
      확인해보세요 ^^

  5. BlogIcon 들고양이 2009.06.08 11:29  댓글주소  수정/삭제  댓글쓰기

    글 상단의 Air프로그램을 설치해서 사용했는데 저런 에러메시지가 떴어요 :) 음...

  6. BlogIcon 들고양이 2009.06.08 21:40  댓글주소  수정/삭제  댓글쓰기

    제가 에러를 덜썼었네요.
    [RPC Fault faultString="HTTP request error" faultCode="Server.Error.Request" faultDetail="Error: [IOErrorEvent type="ioError" bubbles=false cancelable=false eventPhase=2 text="Error #2032" errorID=2032]. URL: http://www.storyq.net/boxes/mine.xml"]가져오는 도중 실패했습니다.

    URL은 정확한데 왜그런지는 잘모르겠습니다..

  7. bumworld 2011.10.26 01:51  댓글주소  수정/삭제  댓글쓰기

    안녕하세요.
    문의가 있어 이렇게 글을 남깁니다.

    navigateToURL로 로그인 하는 페이지를 띄운 다음에 로그인후 callback 페이지에서 결과값을 어떻게 받는지요?
    제가 개념을 잘못 이해 하고 있는건가요?

    제가 생각하고 있는 프로세스는 air의 navigateToURL로 sns 인증 페이지를 띄운다음에 로그인해서 callback url(프로그램 서버측)로 응답을 받아서 받은 결과를 다시 air로 전달할수 있을거라고 생각했는데요.
    이 프로세스가 가능할까요?
    작성하신 글도 navigateToURL로 호출한다음에 결과를 받으시는것 같은데 결과를 어떻게 받는지 모르겠습니다.

    조언좀 부탁드립니다.

 
우선 OAuth인증에 대해서.....
잘 모르겠지만, 오픈되어있는 인증인 듯 합니다-_-;(응?)
어쨌든, 이걸 이용해서 인증을 하고, 인증이 되었으면, 보호된 자원으로부터 접근을 할 수 있습니다.
절차는 이렇습니다.

1. RequestToken얻어오기.
우선 매쉬업애플리케이션을 등록하면, consumer key와 consumer Secret을 받게 됩니다.
이것과 requestToken요청할 수 있는 주소를 알면 RequestToken을 얻을 수 있습니다.

2. Authorize하기.
RequestToken을 가지고, 인증페이지로 가서 로그인을 합니다. 로그인이 완료되면, 서버프로바이더에서는 해당 RequestToken에 대해서 AccessToken을 준비해놨을겁니다.

3. AccessToken얻어오기.
서버프로바이더가 준비한 AccessToken을 요청합니다. 이건 consumer key, consumer secret, requestToken, requestTokenSecret, AccessToken요청할 수 있는 주소를 알면 얻어올 수 있습니다.

4. 해당 AccessToken을 이용해서 자원에 접근하기.
이 AccessToken이 있으면 해당 자원에 접근할 수 있습니다. 이 토큰으로 보호된 자원에 접근할 수 있는 것이죠.

이런 절차의 인증방식을 사용합니다. 너무 간소화했지만, 여기에 가면 자세히 설명이 있습니다.
http://aproxacs.springnote.com/pages/1279246 (aproxacs님 감사해요~)

AIR에서도 OAuth인증을 사용하는 곳에 인증을 할 수 있습니다.
사실 오픈마루가 제공하는 귓속말을 하려고 했는데, 이건 잘 안되더라구요 ㅠ 운영자님께 문의해놨습니다 ㅠ

스토리큐로 해봅시다 ^^ 이 서비스 정말 획기적인데요? OAuth때문에 처음알았습니다 ^^

여기서 사용한 라이브러리는 as3용 oauth라이브러리 http://code.google.com/p/oauth-as3/
암호화 라이브러리 http://code.google.com/p/as3crypto/ 를 사용했습니다.

아...소스코드가 너무 기네-_-;
우선 제가 만든 OAuth요청 클래스입니다.
[code]
package com.mudchobo
{
    import mx.rpc.events.FaultEvent;
    import mx.rpc.events.ResultEvent;
    import mx.rpc.http.HTTPService;
   
    import org.iotashan.oauth.OAuthConsumer;
    import org.iotashan.oauth.OAuthRequest;
    import org.iotashan.oauth.OAuthSignatureMethod_HMAC_SHA1;
    import org.iotashan.oauth.OAuthToken;
   
    public class MudchoboOAuth
    {
        private var consumer_key:String;
        private var consumer_secret:String;
        private var oauth_token:String = "";
        private var oauth_token_secret:String = "";
       
        public function MudchoboOAuth(consumer_key:String, consumer_secret:String)
        {
            this.consumer_key = consumer_key;
            this.consumer_secret = consumer_secret;
        }
       
        // OAuth요청
        public function requestOAuth(params:Object, url:String, method:String,
            resultHandler:Function, faultHandler:Function):void
        {
            var consumerToken:OAuthConsumer = new OAuthConsumer(consumer_key, consumer_secret);
            var oauthToken:OAuthToken = null;
            if (oauth_token != "")
            {
                oauthToken = new OAuthToken(oauth_token, oauth_token_secret);
            }
            var request:OAuthRequest = new OAuthRequest(
                method, url, params, consumerToken, oauthToken);
            var builtUrl:String = request.buildRequest(new OAuthSignatureMethod_HMAC_SHA1());
            trace(builtUrl);
           
            var requestHTTPService:HTTPService = new HTTPService();
            requestHTTPService.url = url;
            requestHTTPService.method = method;
            requestHTTPService.addEventListener(ResultEvent.RESULT, resultHandler);
            requestHTTPService.addEventListener(FaultEvent.FAULT, faultHandler);
            requestHTTPService.send(params);
        }
       
        // Authorize를 위한 로그인 사이트  주소 리턴.
        public function authorizeSite(authrizeURL:String):String
        {
            return authrizeURL + "?oauth_token=" + oauth_token;
        }
       
        // Data파싱 후 oauthToken과 oauthTokenSecret추출
        public function parseData(data:String):void
        {
            var tokenStart:Number = data.indexOf("oauth_token");
            var tokenEnd:Number = data.indexOf("&oauth_token_secret");
            this.oauth_token = data.substring(tokenStart + 12, tokenEnd);
            this.oauth_token_secret = data.substring(tokenEnd + 20);
        }
    }
}
[/code]
메소드중에 requestOAuth메소드가 있는데, 이것은 parameter와 url, method, resultHandler, faultHandler만 지정해주면 자동으로 OAuth에 필요한 파라메터를 만들어서 요청해주는 메소드입니다.
이걸로 RequestToken, AccessToken, 그 외 보호된 자원에 접근하기 위한 요청으로 쓸 수 있습니다.

authorizeSite메소드는 로그인 해주는 사이트로 이동할 때, requestToken을 파라메터로 붙여주는 주소를 리턴해줍니다.

parseData메소드는 요청 후 리턴받은 데이터가 oauth_token=~~~~&oauth_token_secret=~~~ 라고 되어있는 것을 단순히 파싱해서 변수에 저장하는 역할을 합니다.(참고로, 오픈마루의 귓속말서비스 같은 경우 AccessToken을 요청할 때 뒤에 오픈아이디를 같이 붙여줘서 리턴값이 틀립니다. 그걸 참고해서 저걸 사용해야할 듯 싶습니다.)

글이 너무 길어져서 다음글로 패스-_-;
http://mudchobo.tomeii.com/tt/324
 
Posted by 머드초보

댓글을 달아 주세요