How to authenticate on twitter from iphone using asihttp? - objective-c

I used the asihttp library to connect to twitter.
The idea is to send a login request, get the response and extract the session ID/auth code from the response's cookie header. Then you can use that session ID/auth code for consecutive calls.
I don't obtain the auth_code because the authentication fails. how can I fix this?
the code is below:
- (void) login {
NSString *username = #"user";
NSString *password = #"pass";
NSURL *url = [NSURL URLWithString:#"https://twitter.com/sessions?phx=1"];
ASIFormDataRequest *request = [[[ASIFormDataRequest alloc] initWithURL:url] autorelease];
[request addRequestHeader:#"User-Agent" value: #"ASIHTTPRequest"];
[request setPostValue:username forKey:#"session[username_or_email]"];
[request setPostValue:password forKey:#"session[password]"];
[request setDelegate: self];
[request setDidFailSelector: #selector(loginRequestFailed:)];
[request setDidFinishSelector: #selector(loginRequestFinished:)];
[request startAsynchronous];
}
- (void)loginRequestFailed:(ASIHTTPRequest *)request {
NSError *error = [request error];
NSLog(#"login request failed with error: %#", [error localizedDescription]);
}
- (void)loginRequestFinished:(ASIHTTPRequest *)request {
NSString *responseString = [[request responseHeaders] objectForKey:#"Set-Cookie"];
NSLog(#"%#",responseString);
}
I tried to connect from shell and it works.
curl -d 'session[user_or_emai]=user&session[password]=pass' https://twitter.com/sessions

Don't scrape twitter.com. It will end with you getting suspended. Instead use the approved API to integrate with Twitter. You can read about how authentication works with Twitter's API, how you can use xAuth to jumpstart authentication with a users password, and the open source code to help get you started.

Related

oAuth2 retrieve profile email in iOS7

I followed this tutorial and was able to authenticate successfully and got the access token, now I am struggling to understand how can I get email associated with user profile before closing webview and join back my controller.
Any suggestions? I understand that Google has SDK for this, but I don't want to go that route if my requirement is possible with the tutorial I am using.
if (verifier) {
NSString *data = [NSString stringWithFormat:#"code=%#&client_id=%#&client_secret=%#&redirect_uri=%#&grant_type=authorization_code", verifier,client_id,secret,callbakc];
NSString *url = [NSString stringWithFormat:#"https://accounts.google.com/o/oauth2/token"];
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:[NSURL URLWithString:url]];
[request setHTTPMethod:#"POST"];
[request setHTTPBody:[data dataUsingEncoding:NSUTF8StringEncoding]];
NSURLConnection *theConnection=[[NSURLConnection alloc] initWithRequest:request delegate:self];
receivedData = [[NSMutableData alloc] init];
} else {
// ERROR!
}
//Should I need to call another HTTP to retrieve email (or) email already available part of any other response?
If I need to call another HTTP, what URL should be invoked?
Make an authenticated request to the people.get API method with the userId set to me. The person resource has an emails array and the email with type set to account is their verified email.

AFNetworking upload task with credentials (HTTP Basic Auth)

I need to upload video files from my app to a server. I tried doing so via [AFHTTPRequestOperationManager post:parameters:success:failure] but unfortunately kept getting request timeouts. I'm now trying something similar to Creating an Upload Task from the AF Docs.
I read on SO and the AF Docs about setSessionDidReceiveAuthenticationChallengeBlock: and tried to implement the whole upload malarky as follows:
__block ApiManager *myself = self;
// Construct the URL
NSString *strUrl = [NSString stringWithFormat:#"%#/%#", defaultUrl, [self getPathForEndpoint:endpoint]];
NSURL *URL = [NSURL URLWithString:strUrl];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:URL];
[request setHTTPMethod:#"POST"];
// Build a session manager
NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration defaultSessionConfiguration];
AFURLSessionManager *manager = [[AFURLSessionManager alloc] initWithSessionConfiguration:configuration];
// Set authentication handler
[manager setSessionDidReceiveAuthenticationChallengeBlock:^NSURLSessionAuthChallengeDisposition(NSURLSession *session, NSURLAuthenticationChallenge *challenge, NSURLCredential *__autoreleasing *credential) {
*credential = myself.credentials;
return NSURLSessionAuthChallengeUseCredential;
}];
// Create the upload task
NSURLSessionUploadTask *uploadTask = [manager uploadTaskWithRequest:request fromFile:filePath progress:nil completionHandler:^(NSURLResponse *response, id responseObject, NSError *error) {
if (error) {
[myself endpoint:endpoint returnedFailure:error];
} else {
[myself endpoint:endpoint returnedSuccess:responseObject];
}
}];
// and run with it
[uploadTask resume];
The myself.credentials object has been set previously to have the correct username and password. Whenever this request fires, I get 401 unauthorised as a response. I tried putting NSLog(#"CHALLENGE") inside the challenge block above, but it never seems to get called, so AFNetworking isn't giving me a way to supply credentials. I know that this works perfectly well on the server side because I've tested it with Postman.
How can I get AFNetworking to let me supply credentials for HTTP Basic Auth with this upload task?
I'm not sure about AFNetworking's setSessionDidReceiveAuthenticationChallengeBlock, but as long as you have an NSMutableURLRequest you may set the Authorization HTTP Header directly on the request object:
[request setValue:base64AuthorizationString forHTTPHeaderField:#"Authorization"];
Keep in mind that the value must be base64 representation of the username:password string.
Otherwise, for GET, POST, etc. requests on a session manager, you may set the credentials on the request serializer used by the session manager. See:
[AFHTTPRequestSerializer setAuthorizationHeaderFieldWithUsername:password:]
[AFHTTPRequestSerializer clearAuthorizationHeader]

Bit.ly API Objective C retrieve access_token

I have a quick question.
I want the user to enter his username (email) and password and I want to get an access token from the bit.ly api.
I tried so far:
NSString *authStr = [NSString stringWithFormat:#"%#:%#", #"username", #"password"];
NSData *authData = [authStr dataUsingEncoding:NSUTF8StringEncoding];
NSString *authValue = [NSString stringWithFormat:#"Basic %#", [authData base64Encoding]];
[request setValue:authValue forHTTPHeaderField:#"Authorization"];
However this does not work.
What I need is to get this command of curl to run in objective c:
curl -u "username:password" -X POST "https://api-ssl.bitly.com/oauth/access_token"
I know I can set the method to POST but I am not sure how to set username:password :|
I also tried using
curl -u "CLIENT_ID:CLIENT_SECRET" -d "grant_type=password" -d "username=USERNAME" \
-d "password=PASSWORD" https://api-ssl.bitly.com/oauth/access_token
however I still do not know how ti set the input of client id and client secret.
Any help on how I can set those information into the request would help me much!
Jack
Admittedly, things like AFNetworking do make working with NSURLConnection and the like a bit easier, but if you're doing this from scratch, you're close.
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:[NSURL URLWithString:#"https://api-ssl.bitly.com/oauth/access_token"]];
The endpoint for Resource Owner Credential Grants. That will get you the access_token you need to access the rest of our API.
The trickiest part of the flow is the "Authorization" header
NSString *authString = [NSString stringWithFormat:#"%#:%#", #"<YOUR CLIENT ID>", #"<YOUR CLIENT SECRET>"];
NSData *authData = [authString dataUsingEncoding:NSUTF8StringEncoding];
NSString *base64 = [authData base64EncodedStringWithOptions:0];
NSString *authHeader = [NSString stringWithFormat:#"Basic %#", base64];
[request setValue:authHeader forHTTPHeaderField:#"Authorization"];
This will set the Authorization field to: Basic clientID:clientSecret correctly base 64'ed
From there you need to set the body to the request
NSString *postBody = [NSString stringWithFormat:#"grant_type=password&username=%#&password=%#", #"<USERNAME>", #"<PASSWORD>"];
[request setHTTPBody:[postBody dataUsingEncoding:NSUTF8StringEncoding]];
Tell the request it's POST
[request setHTTPMethod:#"POST"];
Then open a NSURLConnection and observe the 3 important delegated methods
NSURLConnection *connection = [[NSURLConnection alloc] initWithRequest:request delegate:self];
[connection start];
You will want to implement:
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData*)data
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
- (void)connectionDidFinishLoading:(NSURLConnection *)connection
Source: I write the Bitly for iPhone app. Hope this helps. Let me know if you have any questions about the API, or the example above.

Loading stringWithContentsofURL that requires credentials

I am trying to parse an HTML page, but the page requires a username/password to access the data.
How do I pass the credentials to the server so I can load the webpage into my NSData object?
UPDATE for Comments Below
Normally if you are using a web browser, it will pop up a login window for you to type in the credentials. When I execute it in iOS, it doesn't give me anything.
Thanks a lot!
Alan
You can use ASIFormDataRequest. Take a look at it here
NSURL *tempUrl = [NSURL URLWithString:#"http://www.yoursitetoparse.com"];
ASIFormDataRequest *request = [[ASIFormDataRequest alloc] init];
request = [ASIFormDataRequest requestWithURL:tempUrl];
[request setDelegate:self];
[request setRequestMethod:#"POST"];
[request setUsername:#"username"]; //Username
[request setPassword:#"password"]; //Password
[request startAsynchronous];
And it's delegate methods:
-(void)requestFailed:(ASIHTTPRequest *)request
{
NSError *error = [request error];
NSLog(#"Failed %# with code %d and with userInfo %#",[error domain],[error code],[error userInfo]);
}
-(void)requestFinished:(ASIHTTPRequest *)request
{
NSLog(#"Finished : %#",[theRequest responseString]);
}

Facebook Graph Api for iOS giving error validating application

I've been running through this tutorial and everything has been going fine until I try to post to a users wall. I can get the user's info, first name, last name, education and such. But when I do the following:
NSURL *url = [NSURL URLWithString:[NSString stringWithFormat:#"https://graph.facebook.com/me/feed"]];
ASIFormDataRequest *request = [ASIFormDataRequest requestWithURL:url];
[request setPostValue:#"Posted from Swangle for iPhone" forKey:#"message"];
[request setPostValue:#"Swangle for Iphone" forKey:#"name"];
[request setPostValue:#"Coming Soon..." forKey:#"caption"];
[request setPostValue:#"Description" forKey:#"description"];
[request setPostValue:_accessToken forKey:#"access_token"];
[request setDidFinishSelector:#selector(postToWallFinished:)];
[request setDelegate:self];
[request startAsynchronous];
- (void)postToWallFinished:(ASIHTTPRequest *)request
{
// Use when fetching text data
NSString *responseString = [request responseString];
NSLog(#"Response String : %# and request : %#", responseString, request);
NSMutableDictionary *responseJSON = [responseString JSONValue];
NSString *postId = [responseJSON objectForKey:#"id"];
NSLog(#"Post id is: %#", postId);
UIAlertView *av = [[[UIAlertView alloc] initWithTitle:#"Sucessfully posted to photos & wall!"
message:#"Check out your Facebook to see!"
delegate:nil
cancelButtonTitle:#"OK"
otherButtonTitles:nil] autorelease];
[av show];
}
I am returned
Post id is : {"error":{"message":"Error validating application.","type":"OAuthException"}}
I know that the access_token is correct because I am allowed to login with it.
Also I created an application on developers.facebook, and am using the correct key to access their DB.
Can someone please advise me, or point me in the right direction to figure this out?
Thanks!
Have you asked for the authorization to post to the user wall?
From Facebook Graph API page:
Authorization
The Graph API as such allows you to easily access all public information about an object. For example, https://graph.facebook.com/btaylor (Bret Taylor) returns all the public information about Bret. For example a user's first name, last name and profile picture are publicly available.
To get additional information about a user, you must first get their permission. At a high level, you need to get an access token for the Facebook user. After you obtain the access token for the user, you can perform authorized requests on behalf of that user by including the access token in your Graph API requests
Take a look here:
https://developers.facebook.com/docs/reference/api/