iOS HTTP Basic Authentication and RestKit
Today morning I was looking for some solution to use authentication with my REST calls to GeoCouch database. I set up the security on the server side but couldn’t get it to work really on the iOS. No joy on stackoverflow.com either :).
Was lucky enough to google up a very small solution project created by @Artsabintsev and hosted on GitHub.
The whole solution is just a single category with a single method extending functionality of the built-in NSMutableURLRequest.
+ (void)basicAuthForRequest:(NSMutableURLRequest *)request withUsername:(NSString *)username andPassword:(NSString *)password
{
// Cast username and password as CFStringRefs via Toll-Free Bridging
CFStringRef usernameRef = (__bridge CFStringRef)username;
CFStringRef passwordRef = (__bridge CFStringRef)password;
// Reference properties of the NSMutableURLRequest
CFHTTPMessageRef authoriztionMessageRef = CFHTTPMessageCreateRequest(kCFAllocatorDefault, (__bridge CFStringRef)[request HTTPMethod], (__bridge CFURLRef)[request URL], kCFHTTPVersion1_1);
// Encodes usernameRef and passwordRef in Base64
CFHTTPMessageAddAuthentication(authoriztionMessageRef, nil, usernameRef, passwordRef, kCFHTTPAuthenticationSchemeBasic, FALSE);
// Creates the 'Basic - <encoded_username_and_password>' string for the HTTP header
CFStringRef authorizationStringRef = CFHTTPMessageCopyHeaderFieldValue(authoriztionMessageRef, CFSTR("Authorization"));
// Add authorizationStringRef as value for 'Authorization' HTTP header
[request setValue:(__bridge NSString *)authorizationStringRef forHTTPHeaderField:@"Authorization"];
// Cleanup
CFRelease(authorizationStringRef);
CFRelease(authoriztionMessageRef);
}
{
// Cast username and password as CFStringRefs via Toll-Free Bridging
CFStringRef usernameRef = (__bridge CFStringRef)username;
CFStringRef passwordRef = (__bridge CFStringRef)password;
// Reference properties of the NSMutableURLRequest
CFHTTPMessageRef authoriztionMessageRef = CFHTTPMessageCreateRequest(kCFAllocatorDefault, (__bridge CFStringRef)[request HTTPMethod], (__bridge CFURLRef)[request URL], kCFHTTPVersion1_1);
// Encodes usernameRef and passwordRef in Base64
CFHTTPMessageAddAuthentication(authoriztionMessageRef, nil, usernameRef, passwordRef, kCFHTTPAuthenticationSchemeBasic, FALSE);
// Creates the 'Basic - <encoded_username_and_password>' string for the HTTP header
CFStringRef authorizationStringRef = CFHTTPMessageCopyHeaderFieldValue(authoriztionMessageRef, CFSTR("Authorization"));
// Add authorizationStringRef as value for 'Authorization' HTTP header
[request setValue:(__bridge NSString *)authorizationStringRef forHTTPHeaderField:@"Authorization"];
// Cleanup
CFRelease(authorizationStringRef);
CFRelease(authoriztionMessageRef);
}
Pretty sweet! To use it use just add the following call when setting up your request object (for an example have a look into previous post about using RestKit to handle JSON).
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:@"http://url.to.the.web.service.com"]];
[NSMutableURLRequest basicAuthForRequest:request withUsername:@"username" andPassword:@"password"];
RKObjectRequestOperation *operation = [[RKObjectRequestOperation alloc] initWithRequest:request responseDescriptors:@[responseDescriptor]];
[operation setCompletionBlockWithSuccess:^(RKObjectRequestOperation *operation, RKMappingResult *result) {
BBoxResponse *bboxResponse = [result firstObject];
NSLog(@"Mapped the bbox response: %@", bboxResponse);
} failure:^(RKObjectRequestOperation *operation, NSError *error) {
NSLog(@"Failed with error: %@", [error localizedDescription]);
}];
[operation start];
[NSMutableURLRequest basicAuthForRequest:request withUsername:@"username" andPassword:@"password"];
RKObjectRequestOperation *operation = [[RKObjectRequestOperation alloc] initWithRequest:request responseDescriptors:@[responseDescriptor]];
[operation setCompletionBlockWithSuccess:^(RKObjectRequestOperation *operation, RKMappingResult *result) {
BBoxResponse *bboxResponse = [result firstObject];
NSLog(@"Mapped the bbox response: %@", bboxResponse);
} failure:^(RKObjectRequestOperation *operation, NSError *error) {
NSLog(@"Failed with error: %@", [error localizedDescription]);
}];
[operation start];
Enjoy!
Hi,
i want to do the same thing like iOS authentication. But RKObjectRequestOperation is missing. What i have to written with replacement?
Regards