65.9K
CodeProject 正在变化。 阅读更多。
Home

在 BlackBerry PlayBook 上使用 OAuth 进行 Twitter 身份验证

starIconstarIconstarIconstarIconemptyStarIcon

4.00/5 (1投票)

2011 年 4 月 18 日

CPOL

5分钟阅读

viewsIcon

15262

如何在 BlackBerry PlayBook 上使用 OAuth 进行 Twitter 身份验证

引言

对于希望代表用户访问第三方数据的所有应用程序开发人员来说,OAuth 正变得至关重要。如果您不熟悉 OAuth,可以在 Hueniverse 上找到一篇优秀的 入门文档

OAuth 是一种允许第三方网站(在本例中为 Twitter)向您的应用程序提供访问权限的方式,而无需用户在您的应用程序中输入其第三方凭据。相反,OAuth 允许您在第三方网站上注册,并使用一系列令牌来最终获得数据访问权限。OAuth 的主要优点之一是,如果应用程序对数据进行了任何恶意操作,用户可以立即撤销访问权限。在此示例中,我将介绍 Twitter API,并使用 Shannon Hicks(Pintley 的创始人)提供的非常优秀的 OAuth-AS3 库。如果您喜欢喝啤酒,可以了解一下 Pintley。

使用 OAuth 的第一步是注册您想要从中获取数据的网站。Twitter 提供了非常简便的方法来通过其 应用程序门户 进行注册。填写必要信息(选择类型为客户端,因为这不是基于 Web 的应用程序),Twitter 将提供一系列随机字符串,您将使用这些字符串来请求数据访问权限,然后再请求数据本身。我们最关心的数据位于 OAuth 1.0a 设置部分,包括消费者密钥、消费者密钥、请求令牌 URL、访问令牌 URL 和授权 URL。

从 Twitter 获取信息的流程如下:

  1. 使用消费者密钥和消费者密钥创建一个 OAuthConsumer 对象。
  2. 使用 OAuthConsumer 对象请求 Twitter 访问数据的权限。
  3. 提示用户授权您的应用程序访问其特定数据。
  4. 请求用户数据并代表其执行操作。

这一切都是通过一系列令牌完成的,直到最后一个阶段,您将获得一个访问令牌,在用户授予您权限后,您将使用该令牌访问数据。我将这些设置为 private 字段变量,以便在此示例中的任何方法中都可以访问它们,并将不变的数据设置为 static 变量。

private static var CONSUMER_SECRET:String = "<YOUR CONSUMER SECRET>";
private static var CONSUMER_KEY:String = "<YOUR CONSUMER KEY>";
private static var REQUEST_TOKEN_URL:String = 
    "https://api.twitter.com/oauth/request_token";
private static var ACCESS_TOKEN_URL:String = "https://api.twitter.com/oauth/access_token";
private static var AUTHORIZE_URL:String = "https://api.twitter.com/oauth/authorize";
private static var API_URL:String = "https://api.twitter.com";
private static var SIGNATURE:OAuthSignatureMethod_HMAC_SHA1 = 
    new OAuthSignatureMethod_HMAC_SHA1();
 
private var _consumer:OAuthConsumer;
private var _authRequest:OAuthRequest;
private var _accessRequest:OAuthRequest;
 
private var _requestToken:OAuthToken;
private var _accessToken:OAuthToken;

第一步是让我们的应用程序使用消费者密钥和消费者密钥登录 Twitter,以便能够发出授权请求。在 init() 函数中,我设置了 UI 并创建了消费者和我的第一个 OAuthRequest 对象,即授权请求。这将连接到 Twitter,并确保消费者密钥和密钥已注册到应用程序。如果已注册,Twitter 将返回一个请求令牌,我可以使用该令牌向用户请求其数据的访问权限。在 init() 方法中,我有一个按钮可以启动此过程,按钮上的事件处理程序使用我的 _authRequest 对象的 buildRequest 方法来正确格式化 URL 字符串,然后我将其发送到 Twitter。

protected function init():void
{    
     _consumer = new OAuthConsumer(CONSUMER_KEY,CONSUMER_SECRET);
     _authRequest = new OAuthRequest(OAuthRequest.HTTP_MEHTOD_GET,REQUEST_TOKEN_URL,
         null,_consumer);
 
     _loginContainer = new Container();
     _loginContainer.align = ContainerAlign.MID;
 
     var button:LabelButton = new LabelButton();
          button.label = "Login to Twitter";
          button.addEventListener(MouseEvent.CLICK,onClick); 
 
     _loginContainer.addChild(_spacer);
     _loginContainer.addChild(button);
     _loginContainer.setSize(1024,600);
     addChild(_loginContainer); 
}
 
protected function onClick(event:MouseEvent):void
{
     var urlRequest:URLRequest = new URLRequest(_authRequest.buildRequest(SIGNATURE));
     var loader:URLLoader = new URLLoader(urlRequest);
     loader.addEventListener(Event.COMPLETE,onRequestComplete);
}

有了该响应,我现在可以构建 _requestToken,以便允许用户授予我访问其数据的权限。下一步是提示用户授权我的应用程序。一旦收到 Twitter 服务器的响应,我就会将其保存为请求令牌,然后构建一个 UI 让用户开始授权过程。

protected function onRequestComplete(event:Event):void
{
     _requestToken = getTokenFromResponse(event.currentTarget.data);
 
     _authContainer = new Container();
     _authContainer.align = ContainerAlign.MID;
 
 
     var authBtn:LabelButton = new LabelButton();
          authBtn.label = "Authorize this application";
          authBtn.addEventListener(MouseEvent.CLICK,onAuthClick);
 
     _authContainer.addChild(_spacer);
     _authContainer.addChild(authBtn);
     _authContainer.setSize(1024,600);
 
     removeChild(_loginContainer);
     addChild(_authContainer);
}

当用户单击按钮时,我的应用程序将发送他们到 Twitter,在那里他们必须登录并授权我的应用程序使用他们的数据。他们会被提示拒绝我的应用程序或允许它。

OAuth-Twitter-PlayBook/authorize_twitter.png

如果他们单击“允许”,Twitter 会提供一个 PIN 码,用户必须将其输入回应用程序以完成授权过程。对于基于 Web 的应用程序,有一个回调 URL,用户在授权应用程序后会被发送到该 URL。但对于客户端应用程序,Twitter 使用 PIN 码并要求用户将其输入回应用程序。

OAuth-Twitter-PlayBook/twitter_pin_entry.png

在代码中,我首先创建了我需要的用于跟踪 PIN 码的 UI 元素,然后使用 Twitter 在请求令牌中提供的密钥创建一个 URLRequest

protected function onAuthClick(event:MouseEvent):void
{
     _verifyContainer = new Container();
     _verifyContainer.align = ContainerAlign.MID;
 
     var label:Label = new Label();
          label.size = 100;
          label.sizeUnit = SizeUnit.PERCENT;
          label.text = "Enter the PIN from Twitter.com";
 
     var font:TextFormat = new TextFormat();
          font.align = TextFormatAlign.CENTER;
          font.bold = true;
          font.size = 24;
 
     text = new TextField();
     text.type = TextFieldType.INPUT;
     text.border = true;
     text.width = 250;
     text.height = 30;
     text.defaultTextFormat = font; 
 
     var getDataBtn:LabelButton = new LabelButton();
          getDataBtn.label = "Get Tweets";
          getDataBtn.addEventListener(MouseEvent.CLICK,onGetDataClick);
 
     _verifyContainer.addChild(_spacer);
     _verifyContainer.addChild(label);
     _verifyContainer.addChild(text);
     _verifyContainer.addChild(getDataBtn);
     _verifyContainer.setSize(1024,600); 
 
     removeChild(_authContainer);
     addChild(_verifyContainer);
 
     var authRequest:URLRequest = new URLRequest(
         'http://api.twitter.com/oauth/authorize?oauth_token='+_requestToken.key);
     navigateToURL(authRequest);
}

一旦用户回来,输入 PIN 码并单击按钮,应用程序就会使用该信息构建请求以获取访问令牌。通过将 PIN 码作为 oauth_verifier 属性传递,我们就可以获得开始从 Twitter 请求数据所需的访问令牌。

protected function onGetDataClick(event:MouseEvent):void
{
     var params:Object = new Object();
          params.oauth_verifier = text.text;
 
     _accessRequest = new OAuthRequest(OAuthRequest.HTTP_MEHTOD_GET,
         ACCESS_TOKEN_URL,params,_consumer,_requestToken);
 
     var accessUrlRequest:URLRequest = new URLRequest(
         _accessRequest.buildRequest(SIGNATURE));
     var accessLoader:URLLoader = new URLLoader(accessUrlRequest);
          accessLoader.addEventListener(Event.COMPLETE,onAccessRequestComplete);
}
 
protected function onAccessRequestComplete(event:Event):void
{
     _accessToken = getTokenFromResponse(event.currentTarget.data);
 
     var mainRequest:OAuthRequest = new OAuthRequest(
         OAuthRequest.HTTP_MEHTOD_GET,API_URL+'/1/statuses/friends_timeline.xml',
         null,_consumer,_accessToken);
 
     var getStatusURLRequest:URLRequest = new URLRequest(
         mainRequest.buildRequest(SIGNATURE));
     var getStatusLoader:URLLoader = new URLLoader(getStatusURLRequest);
          getStatusLoader.addEventListener(Event.COMPLETE,onStatusLoadComplete);
}

请求数据非常直接。使用我们刚刚获得的消费者令牌和访问令牌,我们可以构建一个常规请求,发送出去,然后解析返回的数据。在本例中,我将遍历并显示推文的用户名和状态。

protected function onStatusLoadComplete(event:Event):void
{
     _mainContainer = new Container();
     _mainContainer.flow = ContainerFlow.HORIZONTAL;
 
     var sendTweetContainer:Container = new Container(25);
          sendTweetContainer.containment = Containment.DOCK_TOP;
 
     var font:TextFormat = new TextFormat();
          font.align = TextFormatAlign.CENTER;
          font.bold = true;
          font.size = 24;
 
     twitterTextField = new TextField();
     twitterTextField.type = TextFieldType.INPUT;
     twitterTextField.border = true;
     twitterTextField.width = 500;
     twitterTextField.height = 30;
     twitterTextField.defaultTextFormat = font;
 
     var tweetLabel:LabelButton = new LabelButton();
          tweetLabel.label = "Tweet This";
          tweetLabel.addEventListener(MouseEvent.CLICK,onTweetClick);
 
          sendTweetContainer.addChild(twitterTextField);
          sendTweetContainer.addChild(tweetLabel);
 
     // Code for parsing the XML from the response
     var xml:XML = new XML(event.currentTarget.data);
     var statusList:XMLList = xml.children();
     var arr:Array = new Array();
 
     for(var i:int=0;i<statusList.length();i++)
     {
          var obj:Object = new Object();
               obj.label = statusList[i].user.name.toString() +': ' + 
               statusList[i].text.toString();
          arr.push(obj);
     }
 
     // Create the DataProvider out of the parsed data
     var dataProvider:DataProvider = new DataProvider(arr);
     var list:List = new List();
          list.dataProvider = dataProvider;
          list.size = 100;
          list.sizeUnit = SizeUnit.PERCENT;
          list.setSkin(AlternatingCellRenderer);
 
 
     _mainContainer.addChild(list);
     _mainContainer.addChild(sendTweetContainer);
     _mainContainer.setSize(1024,600);
     removeChild(_verifyContainer);
     addChild(_mainContainer);
}

下一步是启用发送推文的功能。这个功能有点不同。对于之前的所有调用,我们只是创建了一个 params 对象,并将其与 OAuthRequest 一起发送。但是当我们使用 POST 而不是 GET 时,事情就必须有所不同。Soenke Rohde 提供了一个 Flash Twitter 库,我曾参考过,但本质上我们必须从原始请求中剥离 URL 参数,然后将它们重置为 URLVariables 以匹配 POST 请求。

protected function onTweetClick(event:MouseEvent):void
{
     var params:Object = new Object();
          params.status = twitterTextField.text;
 
     // Use the same consumer and accessToken to update the Status
     var tweetRequest:OAuthRequest = new OAuthRequest(
         OAuthRequest.HTTP_MEHTOD_POST,API_URL+'/1/statuses/update.json',
         params,_consumer,_accessToken);
 
     var setStatusURLRequest:URLRequest = new URLRequest(tweetRequest.buildRequest(
          SIGNATURE));
          setStatusURLRequest.method = URLRequestMethod.POST;
 
          // use the replace function to strip out the status
          setStatusURLRequest.url = setStatusURLRequest.url.replace("&status=" + 
              URLEncoding.encode(params.status),"");
 
     // Add the status as a URLVariable since it's a POST operation
     setStatusURLRequest.data = new URLVariables( "status=" + twitterTextField.text  );
 
     var setStatusLoader:URLLoader = new URLLoader(setStatusURLRequest);
          setStatusLoader.addEventListener(Event.COMPLETE,onSetStatusComplete);
}

这基本上就是全部内容了。您可以在 Snipplr 上获取 完整的代码。只需替换您自己的 Twitter 信息,您就可以开始了。

需要记住的一点是,此示例要求您每次使用应用程序时都要进行授权。实际上,这会非常烦人,所以如果您要在生产环境中使用它,您应该将 consumeraccessToken 保存到某个地方,这样就不用每次都创建它们了。

相关文章

  1. 为BlackBerry PlayBook创建自定义列表皮肤
  2. 在 PlayBook 上为列表设置自定义标签
  3. 使用容器类来布局 PlayBook 应用程序
  4. Flex 中手风琴容器的问题
  5. 开始使用 BlackBerry PlayBook 和 Adobe AIR

历史

  • 2011 年 4 月 18 日:初始版本
© . All rights reserved.