Unable to POST data from IPhone using google account authentication - iphone

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.

Related

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

Like a Facebook Post with the use GraphAPI or FQL Query or HTTP Post method

i want to like a post in Facebook, i have post_id , and i am not able to find the FQL Query for liking particular post from the Facebook developer page in IOS SDK.
From Facebook developer page, it says that you can like a post with the used of HTTP POST method it means we can't use GraphAPI or fql.query to like a post.
Can anyone please share HTTP POST URL to like a post in Facebook.
is anyone here who develop the like button functionality for Facebook post using custom button in iOS.
Thanks in advance.
Here is an example if you are using Facebook SDK in iOS:
[FBRequestConnection startWithGraphPath:[NSString stringWithFormat:#"%#/likes", post_id]
parameters:[NSDictionary dictionary]
HTTPMethod:#"POST"
completionHandler:^(FBRequestConnection *connection,
id result,
NSError *error)
{
if (error)
{
NSLog(#"Error: %#", [error localizedDescription]);
}
else
{
NSLog(#"Result: %#", result);
}
}];
I see you are asking for fields(parameters) for HTTP POST URL. An HTTP POST request does not (usually) contain parameters on which you are probably used to when you pass them in a classic GET request such as ?param1=value&param2=value after the script name in some URL.
POST request sends data to the server inside the message body, check out: http://en.wikipedia.org/wiki/POST_(HTTP)
Now that you know that, this is what you can do:
You CAN get the number of likes with a classic GET request, an URL that you can paste into any web browser and get the response, for example:
https://graph.facebook.com/260895413924000_605362559477282/likes?access_token=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
This url will give you a response with all the people who liked that post/photo.
You can leave out the ?access_token=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx if you know the post/photo is public as this one is (https://www.facebook.com/photo.php?fbid=605362542810617&set=a.260905783922963.82517.260895413924000).
If it is not you need to generate one actual access_token(also for posting you NEED to generate one) and for testing you can do it here: https://developers.facebook.com/tools/explorer/
Now if you want to actually like the photo you can't simply form an URL that you can copy/paste inside your browser and which will trigger the like action. That's because browsers do not do POST requests, you need to do it trough code as Ivo Patrick Tudor Weiss suggested or eventually for testing purposes you can do it with curl utility from console like this:
curl --data "access_token=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" https://graph.facebook.com/260895413924005362559477282/likes
and you can undo the like with HTTP DELETE ... like this:
curl --data "access_token=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" -X DELETE https://graph.facebook.com/260895413924000_605362559477282/likes
- UPDATE, for additional questions made by OP in the comments:
It is of course possible to use ASIHTTPRequest to make GET, POST and DELETE HTTP requests. However I would not advise the use of that library for your case. One reason is that the author of ASIHTTPRequest has stopped working on the library, and the other reason is that Facebook SDK for iOS is a better choice since with it you have many other things already taken care for you.
That being said here are the examples:
First type either one of these three combinations depending on what you want:
Get all people who liked the specific post:
(for simplicity I omitted the access_token here but you can append it to the URL if needed)
NSURL *url = [NSURL URLWithString:#"https://graph.facebook.com/260895413924000_605362559477282/likes"];
ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:url];
Like the specific post yourself:
NSURL *url = [NSURL URLWithString:#"https://graph.facebook.com/260895413924000_605362559477282/likes"];
ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:url];
[request appendPostData:[#"access_token=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" dataUsingEncoding:NSUTF8StringEncoding]];
//[request setRequestMethod:#"POST"]; // <--- NOT NEEDED since it is the default if you previously called appendPostData
Unlike the post:
NSURL *url = [NSURL URLWithString:#"https://graph.facebook.com/260895413924000_605362559477282/likes"];
ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:url];
[request appendPostData:[#"access_token=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" dataUsingEncoding:NSUTF8StringEncoding]];
[request buildPostBody];
[request setRequestMethod:#"DELETE"];
Then execute the actual request:
[request startSynchronous];
NSString *response = [request responseString];
NSLog(#"Response: %#", response);
Remember synchronous request is OK for testing but your GUI is going to be unresponsive if you use it on the main thread in an actual app. Learn how to do an asynchronous request here: http://allseeing-i.com/ASIHTTPRequest/How-to-use
As for your iOS example. It would be too much to write all the code here. And you already got the answer from Ivo Patrick Tudor Weiss which is perfectly correct. The only thing that is missing is the boilerplate code that you need to have to authenticate on Facebook and establish an FBSession.
I would advise you to go over this material here: https://developers.facebook.com/docs/getting-started/facebook-sdk-for-ios/
Download the latest SDK which contains also the sample code, and follow the tutorial on Facebook web. Then when you get the basics configured, get back to the answer you got from Ivo.
You can use Graph API to post a like to Facebook post. As it said in documentation here:
http://developers.facebook.com/docs/reference/api/post/
To create a like you need to issue a HTTP POST request to the POST_ID/likes connection with the publish_stream permission. You can suppress the notification created when liking a Post by passing a notify parameter with value of false.

http authentication in devise and rails 3

I have an application which uses devise on rails 3. I would like to enable http authentication so that I can authenticate to my web app from an iPhone app. How can I authenticate from my iPhone app to devise?
Is this secure or should I be authenticating differently?
From the design point of view you have got 3 options:
1) Use basic http authentication: your IPhone app has a secret key -which is baked in your IPhone app code - that uses to authenticate each request with the web app.
Google search: "Devise basic http authentication"
2) You can use https by having a public certificates in your IPhone app and a private certificates on your web app. This is a lot of work to configure right, it is very secure since your IPhone app and the Rails server are exchanging messages over an encrypted channel. The security is also transparent to your rails code since authentication is done at the transport level.
3) The IPhone app connects to the web app using https, get an authentication token that it then uses to make calls to the web app over regular http. More secure than 1 since the key can expire, quite a bit of work to implement and very scalable.
(http://matteomelani.wordpress.com/2011/10/17/authentication-for-mobile-devices/)
Most of apps use solution 1.
Hope this help.
EDIT: to implement http authentication (either basic or digest) I suggest you look at:
http://api.rubyonrails.org/classes/ActionController/HttpAuthentication/Basic.html
and
https://github.com/plataformatec/devise/wiki/How-To:-Use-HTTP-Basic-Authentication
The precise steps will depends on your Rails server stack.
EDIT 2: I do not think Devise provide a way to get the auth_token. I can see you can try several solutions:
when the user logs in the server retrieves the authentication_token and puts it in the cookie. Not very secure unless you encrypt it with a shared secret key.
you can provide a https web service that your IPhone app uses to get a user token. Your IPhone app would make the request right after receiving the user request to sign in.
Sorry I cannot be of more help with some real code.
This largely depends on how you are implementing things on the server side, but we implemented this using Matteo's 3rd option. I have a rails 3.1 implementation using devise. The route to the login is /users/login.json . First build up the JSON body for login with code like this:
NSMutableDictionary *loginDictionary = [NSMutableDictionary dictionary];
NSMutableDictionary *usernamePasswordDictionary = [NSMutableDictionary dictionary];
[usernamePasswordDictionary setObject:username forKey:#"email"];
[usernamePasswordDictionary setObject:password forKey:#"password"];
[loginDictionary setObject:usernamePasswordDictionary forKey:#"user"];
NSData *data = [NSJSONSerialization dataWithJSONObject:loginDictionary options:0 error:&error];
which yields this JSON:
{"user":{"password":"blahblahblah","email":"admin#*****.com"}}
I send a POST url request with code like this:
NSString *postUrlString = [NSString stringWithFormat:#"%#users/login.json", kServerAPIBaseURL];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:postUrlString] cachePolicy:NSURLRequestReloadIgnoringCacheData timeoutInterval:kTimeoutInterval];
[request setHTTPMethod:#"POST"];
[request setValue:#"application/json" forHTTPHeaderField:#"Content-type"];
[request setHTTPBody:data];
The response I get back contains JSON. We configured the server side to return the a session_auth_token:
{
admin = 1;
"created_at" = "2012-01-25T00:15:58Z";
"current_sign_in_at" = "2012-04-04T04:29:15Z";
"current_sign_in_ip" = "75.163.148.101";
email = "admin#******.com";
"encrypted_password" = "*****";
"failed_attempts" = 0;
id = 1;
"last_sign_in_at" = "2012-04-03T03:37:18Z";
"last_sign_in_ip" = "75.163.148.101";
"locked_at" = "<null>";
name = "Joe Smith";
"remember_created_at" = "2012-03-29T20:35:43Z";
"reset_password_sent_at" = "<null>";
"reset_password_token" = "<null>";
"session_auth_token" = "3FRgX6CYlzQJGC8tRWwqEjFaMMFKarQAYKTy3u84M0U=";
"sign_in_count" = 145;
status = 1;
"unlock_token" = "<null>";
"updated_at" = "2012-04-04T04:29:15Z";
}
We store that session_auth_token and then send it back with every request in a header, something like this:
NSMutableURLRequest *postRequest = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:[self postUrlString]]...
[postRequest setHTTPMethod:#"POST"];
[postRequest setValue:#"application/json" forHTTPHeaderField:#"Content-type"];
[postRequest setValue:[self sessionAuth] forHTTPHeaderField:#"X-CSRF-Token"];
[postRequest setHTTPBody:data];
That parameter [self sessionAuth] contains the session_auth_token.
Let me know if you need clarification.

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

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

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] ) ;