AFNetworking 2.0 and HTTP Basic Authentication
Asked Answered
V

3

45

Can't find AFHTTPClient on AFNetworking 2.0, to use:

AFHTTPClient *client = [AFHTTPClient clientWithBaseURL:[NSURL URLWithString:@"http://examplewebsite.com]];

[client setAuthorizationHeaderWithUsername:@"username" password:@"password"];

How it needs to be manage on AFNetworking 2.0?

Virg answered 30/9, 2013 at 19:37 Comment(0)
S
96

AFNetworking 2.0 new architecture use serializers for creating requests and parsing responses. In order to set the authorization header, you should first initialize a request operation manager that replaces the AFHTTPClient, create a serializer and then call the dedicated method to set the header.

For example you code would become:

AFHTTPRequestOperationManager *manager = [[AFHTTPRequestOperationManager alloc] initWithBaseURL:[NSURL URLWithString:@"http://examplewebsite.com"]];
manager.requestSerializer = [AFHTTPRequestSerializer serializer];
[manager.requestSerializer setAuthorizationHeaderFieldWithUsername:@"userName" password:@"password"];

You should read the documentation and the migration guide to understand the new concepts that come with the version 2.0 of AFNetworking.

Surfboarding answered 1/10, 2013 at 8:48 Comment(4)
See also the credential property on AFHTTPRequestOperationManagerArette
Can confirm credential property doesnt appear to work. Ignores anything assigned.Willett
I ran into this issue when migrating from iOS7 to iOS8. For some reason, on iOS8, I had to set the authorization header explicitly, where on iOS7, leaving credentials in the URL alone ("user:[email protected]") was working just fine.Preterite
It is important to note: setAuthorizationHeaderFieldWithUsername:password: will encode using Base64. If your server is decrypting using a different decryption process this will not work UNLESS you configure your server decrypt using Base64.Devour
F
15

Here is an example of performing basic HTTP authentication with AFNetworking 2.0 using NSURLCredential. The advantage of this approach over using the AFHTTPRequestSerializer setAuthorizationHeaderFieldWithUsername:password: method is that you can automatically store the username and password in the keychain by changing the persistence: parameter of NSURLCredential. (See this answer.)

AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];

NSURLCredential *credential = [NSURLCredential credentialWithUser:@"user" password:@"passwd" persistence:NSURLCredentialPersistenceNone];

NSMutableURLRequest *request = [manager.requestSerializer requestWithMethod:@"GET" URLString:@"https://httpbin.org/basic-auth/user/passwd" parameters:nil];

AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc] initWithRequest:request];
[operation setCredential:credential];
[operation setResponseSerializer:[AFJSONResponseSerializer alloc]];
[operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {
    NSLog(@"Success: %@", responseObject);
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
    NSLog(@"Failure: %@", error);
}];
[manager.operationQueue addOperation:operation];
Flump answered 5/1, 2014 at 22:18 Comment(2)
This worked for me for some requests. But multipart requests failed with a "request body stream exhausted" error. I'm not sure without further investigation but I think that your solution makes one request, waits for a 401 response and then retries the request with the given credentials. So multipart requests fail because the stream cannot be re-played. See a similar problem in AFNetworking 1.x github.com/AFNetworking/AFNetworking/issues/661Defend
With iOS8.1 and AF version 2.4.1 this doesn't work for me. Doesn't send the authorization header at all..Nonconformance
R
6

As @gimenete mentions multipart requests will fail when using @titaniumdecoy credential approach as this is applied in the challenge block and the current version of AFNetworking has an issue with this. Instead of using the credential approach you can embed the authentication in the NSMutableRequest header

    NSMutableURLRequest *request = [[AFHTTPRequestSerializer serializer] multipartFormRequestWithMethod:@"PUT"  URLString:path parameters:myParams constructingBodyWithBlock: ^(id <AFMultipartFormData>formData) {
                    [formData appendPartWithFileData:imageData name:imageName fileName:imageName mimeType:@"image/jpeg"];
            } error:&error];    
    NSString *authStr = [NSString stringWithFormat:@"%@:%@", [self username], [self password]];
    NSData *authData = [authStr dataUsingEncoding:NSUTF8StringEncoding];
    NSString *authValue = [NSString stringWithFormat:@"Basic %@", [authData base64EncodedString]];
    [request setValue:authValue forHTTPHeaderField:@"Authorization"];

Where you will need to use a third party BASE64 encoding library such as NSData+Base64.h and .m File from Matt Gallaghers pre ARC BASE64 solution

Romanfleuve answered 12/7, 2014 at 13:1 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.