Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Retrieving Twitter OAuth Token using Social Framework (iOS6)

Tags:

I'm a little confused as to how I get the Twitter OAuth Token using the iOS Social Framework. Assuming I have a Facebook and Twitter account setup on iOS6, and I can get the ACAccount. When I check the ACAccountCredential for the Facebook ACAccount the OAuthToken property is set but for the Twitter ACAccount it isn't. Every other detail for the Twitter ACAccount is set just the ACAccountCredential is not.

To add to the confusion I came across an article on using Reverse Auth to get the OAuth Token (https://dev.twitter.com/docs/ios/using-reverse-auth). This article talks about calling https://api.twitter.com/oauth/request_token and passing in a dictionary of oauth_* params params e.g. consumer_key, nononce, etc. But, surely attaching my ACAccount to the SLRequest serves this purpose? In any event I get back the error "Failed to validate oauth signature and token" when I try this.

So my question is should I be seeing the Twitter OAuth Token in the ACAccountCredential, or should I be using Reverse Auth? and if so, do I need to explicit pass in the NSDictionary containing the oauth_* params or is attaching the ACAccount sufficient?

like image 845
Click Ahead Avatar asked Feb 14 '13 12:02

Click Ahead


People also ask

How to get OAuth access token for Twitter?

Generating access tokensLogin to your Twitter account on developer.twitter.com. Navigate to the Twitter app dashboard and open the Twitter app for which you would like to generate access tokens. Navigate to the "Keys and Tokens" page. Select 'Create' under the "Access token & access token secret" section.

What is access_ token in Twitter?

Twitter allows you to obtain user access tokens through the 3-legged OAuth flow, which allows your application to obtain an access token and access token secret by redirecting a user to Twitter and having them authorize your application.


2 Answers

Let's answer this in a few steps, there are a few things that need addressing/clarifying.

ACAccountCredential

This object is used in co-ordination with an ACAccount object, in order for the accounts framework to be able to authenticate the user for a particular account. It is not designed to be read at will; it is only supposed to be used when you need to save an account to the accounts framework.

Documentation from Twitter states that you need to populate an ACAccountCredential if you're migrating to the accounts framework to manage your user's accounts, instead of using your own servers, or in the case of older iOS application, managing the accounts yourself locally.

Apple clearly say in their documentation that the credentials aren't able to be read after the account has been saved to the accounts framework.

For privacy reasons, this property is inaccessible after the account is saved.

As such, this is the reason why Twitter provide the ability for using reverse authentication, in case you still need the OAuth token for server side management. I don't know why you're able to get it for a Facebook account, but for Twitter you can't jump straight to a pre saved ACAccountCredential.

Using Twitter's Reverse Auth

The documentation provided by Twitter (linked in your question) makes the process fairly clear on what you need to do in order to access the OAuth access token, but I'll try to clarify a few things that may not be so clear.

There is an extra framework required, in addition to the Accounts and Twitter framework, to make this work; Social.framework. Make sure this is imported, as this will make requesting the token considerably simpler.

As for the request you need to send, Twitter is not aware of ACAccounts. Remember this reverse auth process is not specific to iOS, it can be done by any computing device with access to the web. As such, you need to send a HTTP POST request to https://api.twitter.com/oauth/request_token with the specified parameters (OAuth standard ones + x_auth_mode). A bit more clarity on the required parameters can be found here, but the link in your question will also make clear which parameters are required. You will be required to provide your own nonce, and other parameter values.

You can use the SLRequest class or AFNetworking to make your POST request to Twitter, passing in an NSDictionary for your parameter values (as seen in the code sample in Twitter's documentation for access_token).

And that's it

After answering those two points, I think it's clear that you'll need to use reverse authentication in order to access the correct OAuth token for your needs. The Twitter documentation makes it clear on what you need to do (it even provides code samples that you can use), but you do need to be aware of general OAuth request/response management in order to do so. You can't simply attach an ACAccount, you need to populate a dictionary with the required OAuth parameters, and then pass this in to your HTTP POST request to request_token. I have provided a considerable number of references for you to refer to, and I hope that'll put you on the right path.

like image 110
WDUK Avatar answered Oct 13 '22 10:10

WDUK


Assuming you are going to try this on >= iOS 5.0, here is an easier way to get the access token. Irrespective of whether you are using Twitter.framework or Social.framework, the way both work is by doing the request signing for you. We use either TWRequest or SLRequest to create your request. Once we are done with this, we get the NSURLRequest object from either of these.

The trick here is to look at the headers of this NSURLRequest. As we have to specify, as per OAuth standards, a few OAuth parameters and oauth_token being one of them, it should be easy to extract it out. Below is a way to get this out.

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;     } } 

May be this code can be optimized more but you get the idea. The variable accessToken will have the actual access token.

like image 32
Deepak G M Avatar answered Oct 13 '22 12:10

Deepak G M