使用社交框架检索Twitter OAuth令牌(iOS6)

时间:2013-02-14 12:22:38

标签: ios twitter-oauth social-framework

我对如何使用iOS社交框架获取Twitter OAuth令牌感到困惑。假设我在iOS6上设置了Facebook和Twitter帐户,我可以获得ACAccount。当我检查Facebook ACAccount的ACAccountCredential时,OAuthToken属性已设置,但对于Twitter ACAccount,则不是。 Twitter ACAccount的其他每个细节都设置为ACAccountCredential不是。

为了增加混乱,我遇到了一篇关于使用Reverse Auth获取OAuth令牌(https://dev.twitter.com/docs/ios/using-reverse-auth)的文章。本文讨论调用https://api.twitter.com/oauth/request_token并传入oauth_ * params params字典,例如consumer_key,nononce等等。但是,确实将我的ACAccount附加到SLRequest是为了这个目的吗?在任何情况下,当我尝试这个时,我都会收到错误“无法验证oauth签名和令牌”。

所以我的问题是我应该在ACAccountCredential中看到Twitter OAuth令牌,还是应该使用Reverse Auth?如果是这样,我是否需要显式传递包含oauth_ *参数的NSDictionary或者附加足够的ACAccount?

4 个答案:

答案 0 :(得分:17)

让我们通过几个步骤回答这个问题,有一些事情需要解决/澄清。

ACAccountCredential

此对象用于与ACAccount对象协调,以便帐户框架能够为特定帐户验证用户身份。它不是为了随意阅读而设计的;它只应在您需要将帐户保存到帐户框架时使用。

Documentation from Twitter指出,如果您要迁移到帐户框架来管理用户的帐户,而不是使用自己的服务器,或者在较旧的iOS应用程序中管理帐户,则需要填充ACAccountCredential你自己在当地。

Apple clearly say in their documentation帐户保存到帐户框架后无法读取凭据。

  

出于隐私原因,保存帐户后无法访问此媒体资源。

因此,这就是Twitter提供使用反向身份验证的能力的原因,以防您仍需要OAuth令牌进行服务器端管理。我不知道你为什么能够获得Facebook帐户,但对于Twitter你不能直接跳到预先保存的ACAccountCredential。

使用Twitter的反向验证

Twitter提供的文档(在您的问题中链接)使得该过程非常清楚您需要做什么才能访问OAuth访问令牌,但我会尝试澄清一些可能不太清楚的事情

除了帐户和Twitter框架之外,还需要一个额外的框架来完成这项工作; Social.framework。确保导入它,因为这将使请求令牌变得更加简单。

至于您需要发送的请求,Twitter不知道ACAccounts。请记住,此反向身份验证过程并非特定于iOS,可以通过任何可访问Web的计算设备来完成。因此,您需要使用指定的参数(OAuth标准值+ https://api.twitter.com/oauth/request_token)向x_auth_mode发送HTTP POST请求。更清楚了解所需参数can be found here,但您问题中的链接也会明确哪些参数是必需的。您需要提供自己的随机数和其他参数值。

您可以使用SLRequest类或AFNetworking向Twitter发送POST请求,并为您的参数值传入NSDictionary(如Twitter access_token文档中的代码示例所示。

就是这样

在回答了这两点后,我认为很明显您需要使用反向身份验证才能根据需要访问正确的OAuth令牌。 Twitter文档清楚地说明了您需要做什么(它甚至提供了您可以使用的代码示例),但您需要了解一般的OAuth请求/响应管理才能执行此操作。您不能简单地附加ACAccount,您需要使用所需的OAuth参数填充字典,然后将其传递给您对request_token的HTTP POST请求。我已经提供了大量的参考资料供你参考,我希望这会让你走上正确的道路。

答案 1 :(得分:7)

假设您要在> = iOS 5.0上尝试此操作, 这是获取访问令牌的更简单方法。无论您使用的是Twitter.framework还是Social.framework,两者的工作方式都是为您执行请求签名。我们使用TWRequest或SLRequest来创建您的请求。完成此操作后,我们将从其中任何一个获取NSURLRequest对象。

这里的技巧是查看此NSURLRequest的标头。我们必须根据OAuth标准指定一些OAuth参数,并将oauth_token作为其中之一,因此应该很容易将其解压缩出来。以下是解决此问题的方法。

NSURLRequest * reqTemp = /* Prepare the request using either Twitter.framework or Social.framework */;
NSDictionary * dictHeaders = [reqTemp allHTTPHeaderFields];

NSString * authString = dictHeaders[@"Authorization"];
NSArray * arrayAuth = [authString componentsSeparatedByString:@","];
NSString * accessToken;
for( NSString * val in arrayAuth ) {
    if( [val rangeOfString:@"oauth_token"].length > 0 ) {
        accessToken =
            [val stringByReplacingOccurrencesOfString:@"\""
                                           withString:@""];
        accessToken =
            [accessToken stringByReplacingOccurrencesOfString:@"oauth_token="
                                                        withString:@""];
        break;
    }
}

可能这个代码可以进行更多优化,但你明白了。变量accessToken将具有实际的访问令牌。

答案 2 :(得分:3)

实际上,如果您唯一关心的是检索OAuth令牌,则可以使用Social框架以非常简单的方式访问它。 文档中包含一个名为:

的方法
func preparedURLRequest() -> NSURLRequest!
  

返回值与OAuth兼容的NSURLRequest对象,允许使用   应用程序代表用户执行操作,同时保留用户的密码   私人的。默认情况下,NSURLRequest被签名为OAuth1,或者OAuth2 by   根据用户的帐户添加适当的令牌。

     

讨论使用此方法在发送前修改您的请求。通过   正确设置帐户,此方法将自动添加任何   必要的代币。

因此,您只需创建一个这样的签名SLRequest

let accounts = self.accountStore.accountsWithAccountType(type)
let request = SLRequest(
                forServiceType: SLServiceTypeTwitter,
                requestMethod: .GET,
                URL: NSURL(string: "https://api.twitter.com/1.1/account/verify_credentials.json"),
                parameters: ["include_entities": true])      
request.account = accounts?.first as? ACAccount

现在只需访问request.preparedURLRequest().allHTTPHeaderFields(),您就会看到其中的oauth_token

但是你没有Secret令牌(因为它用于根据twitter documentation生成oauth_signature),这使得服务器端管理无用。

答案 3 :(得分:1)

查看此项目https://github.com/seancook/TWReverseAuthExample。有TWAPIManager类为您完成这项工作。