AFNetworking upload task with credentials (HTTP Basic Auth) - objective-c

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]

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.

How to get a new access token after expiration using OAuth 2.0 along with Youtube API in iOS application

I am using the Youtube Api in my iPad application. i managed to get authenticated and get the access token using the OAuth 2.0.
my problem is that the token expires after one hour and i don't know how to get a new one using the refresh-token without going through the authentication process again.
i am using XCode 4.5 and iOS 5.1 & 6
According do the documentation
If your application obtains a refresh token during the authorization process, then you will need to periodically use that token to obtain a new, valid access token. Server-side web applications, installed applications, and devices all obtain refresh tokens.
So if you already have your refresh token, you just need to perform a POST request configured as follows
POST /o/oauth2/token HTTP/1.1
Host: accounts.google.com
Content-Type: application/x-www-form-urlencoded
client_id=21302922996.apps.googleusercontent.com&
client_secret=<YOUR CLIENT SECRET>
refresh_token=<YOUR REFRESH TOKEN>
grant_type=refresh_token
and you'll get back a response like
{
"access_token":<A NEW ACCESS TOKEN>,
"expires_in":<AN EXPIRING TIME>,
"token_type":"Bearer"
}
Here is the full code to refresh the accessToken using AFNetworking to make the request:
NSString *refreshToken = <YOUR_REFRESH_TOKEN>;
NSString *post = [NSString stringWithFormat:#"client_secret=%#&grant_type=refresh_token&refresh_token=%#&client_id=%#",kYouTubeClientSecret,refreshToken,kYouTubeClientID];
NSData *postData = [post dataUsingEncoding:NSASCIIStringEncoding allowLossyConversion:YES];
NSString *postLength = [NSString stringWithFormat:#"%d", [postData length]];
NSURL *url = [NSURL URLWithString:#"https://accounts.google.com/o/oauth2/token"];
AFHTTPClient *httpClient = [[AFHTTPClient alloc] initWithBaseURL:url];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
[request setHTTPMethod:#"POST"];
[request setValue:postLength forHTTPHeaderField:#"Content-Length"];
[request setValue:#"application/x-www-form-urlencoded" forHTTPHeaderField:#"Content-Type"];
[request setHTTPBody:postData];
AFHTTPRequestOperation *httpRequest = [httpClient HTTPRequestOperationWithRequest:request
success:^(AFHTTPRequestOperation *operation, id responseObject) {
NSDictionary *json = [NSJSONSerialization JSONObjectWithData:responseObject options:kNilOptions error:nil];
NSString *newAccessToken = json[#"access_token"];
NSLog(#"received new accessToken = %#",newAccessToken);
// store accessToken here
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(#"error refreshing token: %#",[error localizedDescription]);
}];
[httpClient enqueueHTTPRequestOperation:httpRequest];

Basic authorization in NSMutableURLRequest isn't working

I'm trying to add basic authorization to my request header. The code below compiles and I dont get any runtime errors. However, on the server side I do not see the "Authorization" in the header at all.
I was able to implement the didReceiveAuthenticationChallenge method and that works, but I dont understand why I have to do it this way. I simply want to always add basic auth to every request.
I'm not interested in using ASIHTTPRequest.
Thanks for the help!
This is my code below:
NSURL *url = [[NSURL alloc] initWithString:#"http://localhost:8000/MyWebService"];
self.userName = #"myusername";
self.password = #"mypassword";
NSMutableString *credentials = [[NSMutableString alloc] initWithFormat:#"%#:%#", userName, password];
NSString *encodedCredentials = [[credentials dataUsingEncoding:NSUTF8StringEncoding] base64EncodedString];
NSString *authHeader = [NSString stringWithFormat:#"Basic %#", encodedCredentials];
NSMutableURLRequest* req = [NSMutableURLRequest requestWithURL:url cachePolicy:NSURLRequestReloadIgnoringCacheData timeoutInterval:5];
[req addValue:authHeader forHTTPHeaderField:#"Authorization"];
self.urlConnection = [[NSURLConnection alloc] initWithRequest:req delegate:self startImmediately:YES];
if (self.urlConnection) {
self.receivedData = [NSMutableData data];
}
else {
errorLabel.text = #"Error connecting to the server";
}
The didReceiveAuthenticationChallenge is the way it works in iOS and the easiest way to do it. It will be submitted with every request (with the challenge). Guess that's not what you want to hear=)
I guess you have tried using different tutorials. I've used this one to authenticate before:
Basic access Auth, iOS

How to authenticate on twitter from iphone using asihttp?

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.

NSURLCredential not working for synchronuos request in iphone

I am using Synchronous request and passing the credentials but I am getting authentication error in response. Below is my code of request and response from server.
Request:-
NSURLCredential *userCredentials = [NSURLCredential credentialWithUser:#"username"
password:#"paswd"
persistence:NSURLCredentialPersistenceForSession];
NSURLProtectionSpace *space = [[NSURLProtectionSpace alloc] initWithHost:#"http://webaddress.inc.com"
port:80
protocol:#"http"
realm:#"webaddress.inc.com"
authenticationMethod:nil];
[[NSURLCredentialStorage sharedCredentialStorage] setCredential:userCredentials
forProtectionSpace:space];
NSMutableURLRequest *urlRequest = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:#"http://webaddress.inc.com"]
cachePolicy:NSURLCacheStorageNotAllowed
timeoutInterval:30];
NSURLResponse *response;
NSError *error;
NSData *returnData = [NSURLConnection sendSynchronousRequest:urlRequest
returningResponse:&response
error:&error];
/////////// Response
401 Authorization Required
Note: If I am sending the request with async request it is working fine as in that case
didReceiveAuthenticationChallenge is giving them the required credentials when asked for.
I am sure there might be something missing in my code.
Waiting for your valuable inputs.
Have you ever tried ASIHTTPRequest which makes easier http operations in IPhone enviroment. And It has really simple and good documentation. I used to use it inside of my projects, It was working awesome.