Twitter (xCode/iPhone) How can I successfully authenticate through oAuth? - iphone

I am trying to explain in pseudo. I followed the following URL: http://dev.twitter.com/pages/auth#intro
There I read the authentication procedure. I builded a script that successfully creates a proper signature string for the oAuth properties. But then I am stuck.
I build an Authentication string for the 'Authentication' header field.
OAuth oauth_callback="http%3A%2F%2Flocalhost%3A3005%2Fthe_dance%2Fprocess_callback%3Fservice_provider_id%3D11", oauth_consumer_key="GDdmIQH6jhtmLUypg82g", oauth_nonce="QP70eNmVz8jvdPevU3oJD2AfF7R7odC2XJcn4XlZJqk", oauth_signature="8wUi7m5HFQy76nowoCThusfgB%2BQ%3D", oauth_signature_method="HMAC-SHA1", oauth_timestamp="1272323042", oauth_version="1.0"
But now I am wondering what to do with it. I try to sent it in the header
NSMutableURLRequest *urlRequest = [[[NSMutableURLRequest alloc] initWithURL:[NSURL URLWithString:#"http://api.twitter.com/oauth/request_token"] cachePolicy:cachePolicy timeoutInterval:timeoutInterval] autorelease];
[urlRequest setHTTPMethod:#"POST"];
[urlRequest addValue:authenticationString forHTTPHeaderField:#"Authorization"];
But when retrieving the content I get:
"Failed to validate oauth signature
and token"
Anyone familiar with this error? Because the oauth signature is in there and the token should not be required because it is calling the request_token URL.

you should use xAuth for mobile clients' authentication with twitter...
google xAuthTwitterEngine by Aral Balkan, basically he modified MGTwitterEngine to do the xAuth authentication using the OAuthConsumer open source library
cheers

Related

ios managing authentication tokens from NSURLRequest / HTTP request

When I make a POST request to sign in from within the iPhone app I am developing, the request returns an authentication token that I can successfully store in an NSString to be used throughout the rest of the app.
However, for any request after the sign in, I must pass it this authentication token so the request knows that a user is logged in. What is the complete way to do this for an NSURLRequest / what parameters/values must i specify for the NSURLRequest? Thank you in advance.
These NSURLRequest methods might help you
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:[NSURL URLWithString:#"yoururl.com"]];
[request setHTTPMethod: #"POST" ];
[request setValue:#"yourtoken" forHTTPHeaderField:#"header field"];
[request setHTTPBody: dataifneeded ];

Changes coming in Version 1.1 of the Twitter API in iPhone

I am using twitter API version V1.0 for my new iphone application .I am successfully able to do this using twitters v1.0 of the API and all works perfectly. Simply making a request to http://api.twitter.com/1/statuses/user_timeline.json?screen_name=userid retrieves all the information that I require.
since v1.0 has been deprecated and V1.1 requires authentication for each request, I get a bad authorization error (HTTP response status: 400)using this API.
What are the Changes i need to do in my appication .how to generate OAuth request headers,Do i need register my application ?How can i get authentication for new version?
I hope the above makes sense and any help would be appreciated.
Thanks in advance.
Visit https://dev.twitter.com/docs/ios/making-api-requests-slrequest
https://dev.twitter.com/docs/oauth/xauth
u can get the authentication using following method:
NSString *base64 = #"Basic NFRLWGlZY3l1aHJ4OVJaUWI5RW5BOmdVMXlvcVV6YzBNZUhUQmFXdVRZU2NtZHlIWDFOZXhwZmxqRE16bm01aw==";
//oauth_consumer_secret,oauth_consumer_key
NSURL *urlAPI = [NSURL URLWithString:[NSString stringWithFormat:#"https://api.twitter.com/oauth2/token"]];
ASIFormDataRequest *request = [ASIFormDataRequest requestWithURL:urlAPI];
[request setDelegate:self];
[request setRequestMethod:#"POST"];
[request addRequestHeader:#"Authorization" value:base64];
[request addRequestHeader:#"Content-Type" value:#"application/x-www-form-urlencoded;charset=UTF-8"];
[request setPostValue:#"client_credentials" forKey:#"grant_type"];
In response u will get the authtoken for your application like this
{"token_type":"bearer","access_token":"AAAAAAAAAAAAAAAAAAAAAMddRQAAAAAAXRP6Axur1RS%2Fv9YFtJ7TijyPAGo%3DpmNowwOGf3dZTHDiH2gnCcv7qNIyGZcyV2IW5YFTBs"}

Posting JSON from iOS to Rails 3.1 (Stringify_keys error)

I'm trying to create a user acount on my rails backend via json from an iPhone app. Here is what is currently being posted to the server:
Started POST "/patients" for 127.0.0.1 at 2011-11-27 20:52:29 -0800
Processing by PatientsController#create as HTML
Parameters: {"patient"=>"{\"password\":\"password\",\"password_confirmation\":\"password\",\"email\":\"testagain\"}"}
WARNING: Can't verify CSRF token authenticity
Completed 500 Internal Server Error in 1ms
NoMethodError (undefined method `stringify_keys' for #<String:0x00000104a354f8>):
app/controllers/patients_controller.rb:43:in `new'
app/controllers/patients_controller.rb:43:in `create'
By posting straight from the browser these are the paramaters that are submitted:
Parameters: {"utf8"=>"✓", "authenticity_token"=>"H2iYdzdfokQs91AAozb+taMTdV2y5xLRaCni5XKQN4w=", "patient"=>{"email"=>"test", "password"=>"[FILTERED]", "password_confirmation"=>"[FILTERED]"}, "commit"=>"Create Patient"}
From what I have read elsewhere the stringify_keys means that the actions expects a hash (which I thought I almost reconstructed) since I am using this code to create a new user:
#patient = Patient.new(params[:patient])
I also believe that the authenticity token doesn't matter if I'm posting using JSON format... does it matter?
Over all question: Is this the right approach to be posting to a rails backend from an iphone app? Recreating the parameters hash? Would appreciate any nudges in the right direction.
For completeness sake here is the code snippet I'm using to post from my iOS app:
NSDictionary *json = [self createSignUpDictionary];
NSURL *url = [NSURL URLWithString:#"http://localhost:3000/patients"];
ASIFormDataRequest *request = [ASIFormDataRequest requestWithURL:url];
[request addRequestHeader:#"Content-Type" value:#"application/json"];
[request addRequestHeader:#"Accepts" value:#"application/json"];
[request setPostValue:[json JSONString] forKey:#"patient"];
[request startAsynchronous];
You will most likely have to disable the authentication token verification for your action.
Just put the following line in your controller and everything should work.
protect_from_forgery :except => :index
However if you do that make sure that you have some form of custom protection on your #create function. You can read this for more info: http://api.rubyonrails.org/classes/ActionController/RequestForgeryProtection/ClassMethods.html

Difficulties signing in to Twitter from iPhone

I'm using MGTwitterEngine to add Twitter functionality to my app. It's very easy to simply prompt the user for a username and password and then start posting. Strangely, however, I've noticed other apps (eg Foursquare and Brightkite) require you to visit their website to associate your Twitter account with your foursquare/brightkite/whatever account.
Why do they do it this way?
Is there a reason why my app shouldn't prompt the user for a Twitter username and password, even though it would be so easy?
Thanks a bunch!
Tristan
This is because you're using Basic Auth, which is just a username/password. Most new Twitter apps use the more robust OAuth, which requires you to visit Twitter.com to allow access, but does not require a username/password. The Twitter API docs claim that support for Basic Auth will be dropped soon, so you should be using OAuth as well.
Twitter supports OAuth, which allows you to access their account without asking for their password directly.
The main concern is security. What happens if/when your database gets hacked? The attackers will have access to all of your user's twitter passwords.
On hte other hand, those sites don't store their users passwords; if they get hacked, twitter can easily disable the oauth credentials, locking out any attackers before they can do harm.
Use OAuth; it's a lot safer.
Just replace YOUR_TWITTER_USERNAME and YOUR_TWITTER_PASSWORD. The code below has to be included in your viewController.m
NSMutableURLRequest *theRequest=[NSMutableURLRequest requestWithURL: [NSURL
URLWithString: #”http: //YOUR_TWITTER_USERNAME: YOUR_TWITTER_PASSWORD#twitter. com/
statuses/update. xml”]
cachePolicy:NSURLRequestUseProtocolCachePolicy
timeoutInterval: 60. 0] ;
[theRequest setHTTPMethod: #”POST”] ;
[theRequest setHTTPBody: [[NSString stringWithFormat: #”status=%#”,
themessage] dataUsingEncoding: NSASCIIStringEncoding] ] ;
NSURLResponse* response;
NSError* error;
NSData* result = [NSURLConnection sendSynchronousRequest:theRequest
returningResponse: &response error: &error] ;
NSLog( #”%#”, [[[ NSString alloc] initWithData: result
encoding: NSASCIIStringEncoding] autorelease] ) ;

Unable to POST data from IPhone using google account authentication

I'm working on an IPhone application that works with a Google App Engine application. I manage to get logged by using a google account and I get the authentication token. I'm also able to GET data from the GAE service (I did it after reading another question written here) but now I need to POST data so I need to send the authentication token in the header of the POST request. I tried several options but none of them worked.
Here is the code I use to put that auth into the header:
NSString* urlStr = [NSString stringWithFormat:#"%#%#", HOST, url];
NSMutableURLRequest* urlPost = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:urlStr]];
NSString* authStr = [NSString stringWithFormat:#"GoogleLogin auth=%#", token];
[urlPost addValue:authStr forHTTPHeaderField:#"Authorization"];
but it doesn't work.
Any help?
You need to use [request setHTTPMethod: #"POST"] and [request setHTTPBody: postdata] to properly configure the POST components. See the NSMutableURLRequest docs for more details.
Whenever I'm troubleshooting a problem related to HTTP, the first tool I'll grab is Charles HTTP Proxy. It will show you the entire request and response for closer examination.
If you're authenticating against an App Engine app, you need to obtain and send an authentication cookie, rather than using the GoogleLogin authentication. The source of appengine_rpc.py in the Python SDK demonstrates how.