使用Social框架(iOS6)获取Twitter OAuth令牌

23

我有点困惑如何使用iOS Social Framework获取Twitter OAuth Token。假设我在iOS6上设置了Facebook和Twitter帐户,并且可以获取ACAccount。当我检查Facebook ACAccount的ACAccountCredential时,OAuthToken属性已设置,但是对于Twitter ACAccount则没有设置。Twitter ACAccount的每个其他细节都设置了,只有ACAccountCredential没有设置。

增加混乱的是,我遇到了一篇关于使用Reverse Auth获取OAuth Token(https://dev.twitter.com/docs/ios/using-reverse-auth)的文章。本文讲述了调用https://api.twitter.com/oauth/request_token并传递包含oauth_*参数的字典(例如consumer_key、nononce等)的过程。但是,将我的ACAccount附加到SLRequest上肯定能够实现此目的,不是吗?无论如何,当我尝试这样做时,返回错误“无法验证oauth签名和令牌”。

因此,我的问题是:我应该在ACAccountCredential中看到Twitter OAuth Token,还是应该使用Reverse Auth?如果需要,我是否需要显式传递包含oauth_*参数的NSDictionary,或者将ACAccount附加就足够了?

4个回答

17

让我们分几步来回答,有几个需要解释/澄清的事情。

ACAccountCredential

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

Twitter的文档指出,如果您要迁移到帐户框架以管理用户帐户,而不是使用自己的服务器,或者在旧版iOS应用程序中自行管理帐户,则需要填充ACAccountCredential。

苹果在他们的文档中明确指出,一旦将帐户保存到帐户框架后,凭据将无法读取。

出于隐私原因,此属性在保存帐户后无法访问。

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

使用Twitter的反向身份验证

Twitter提供的文档(链接在您的问题中)清楚地说明了您需要执行哪些操作才能访问OAuth访问令牌,但我将尝试澄清一些可能不太清楚的事情。

除了Accounts和Twitter框架之外,还需要另一个框架才能使其工作;Social.framework。 确保导入此框架,因为这将使请求令牌变得更加简单。

关于您需要发送的请求,Twitter不了解ACAccounts。请记住,此反向身份验证过程并不特定于iOS,任何具有访问Web的计算设备都可以完成。因此,您需要使用指定参数(OAuth标准参数+x_auth_mode)发送HTTP POST请求到https://api.twitter.com/oauth/request_token。有关所需参数的更多清晰信息可以在此处找到,但您问题中的链接也将明确说明所需的参数。您需要提供自己的nonce和其他参数值。
您可以使用SLRequest类或AFNetworking向Twitter发出POST请求,为参数值传递NSDictionary(如Twitter文档中的access_token代码示例所示)。
就是这样了。回答了这两个问题之后,我认为明确了您需要使用反向身份验证来访问所需的正确OAuth令牌。 Twitter文档清楚说明了您需要做什么(甚至提供了可供使用的代码示例),但是您需要了解通用的OAuth请求/响应管理才能这样做。您无法简单地附加ACAccount,而是需要填充包含所需OAuth参数的字典,然后将其传递给request_token的HTTP POST请求。我为您提供了大量参考资料,希望能为您指引方向。

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将拥有实际的访问令牌。

3

如果您只关心获取OAuth令牌,那么使用Social框架访问它的方法非常简单。 文档中有一个名为:

func preparedURLRequest() -> NSURLRequest!

返回值:一个OAuth兼容的NSURLRequest对象,使应用程序可以代表用户行事,同时保持用户的密码私密。默认情况下,NSURLRequest被OAuth1签名,或根据用户账户添加适当的令牌来进行OAuth2签名。
讨论:使用此方法在发送请求之前修改请求。通过正确设置帐户,此方法将自动添加任何必要的令牌。
因此,您只需像这样简单地创建一个已签名的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 token(因为它用于根据twitter文档生成oauth_signature),这使得它对服务器端管理相当无用。


1

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接