Skip to content

Instantly share code, notes, and snippets.

@sco
Created February 17, 2011 19:48
Show Gist options
  • Save sco/832499 to your computer and use it in GitHub Desktop.
Save sco/832499 to your computer and use it in GitHub Desktop.
Using XAuth to exchange username/password credentials for a OAuth access token
// UITextFieldDelegate method, called when the "Return" key is pressed.
// Either advance the cursor to the next empty field, or submit the form.
//
- (BOOL)textFieldShouldReturn:(UITextField *)textField {
if([usernameField.text length] == 0) {
[usernameField becomeFirstResponder];
} else if ([passwordField.text length] == 0) {
[passwordField becomeFirstResponder];
} else {
[textField resignFirstResponder];
[self getAccessToken];
}
return YES;
}
// Given a username and password, request an access token via XAuth and display
// a "loading" overlay box.
//
- (void)getAccessToken {
OAConsumer *consumer = [[[OAConsumer alloc] initWithKey:consumerKey secret:consumerSecret] autorelease];
NSURL *URL = [NSURL URLWithString:authURLString];
OAMutableURLRequest *request = [[[OAMutableURLRequest alloc] initWithURL:URL consumer:consumer token:nil realm:nil signatureProvider:nil] autorelease];
[request setHTTPMethod:@"POST"];
[request setParameters:[NSArray arrayWithObjects:
[OARequestParameter requestParameter:@"x_auth_mode" value:@"client_auth"],
[OARequestParameter requestParameter:@"x_auth_username" value:self.usernameField.text],
[OARequestParameter requestParameter:@"x_auth_password" value:self.passwordField.text],
nil
]];
OADataFetcher *dataFetcher = [[[OADataFetcher alloc] init] autorelease];
[dataFetcher fetchDataWithRequest:request delegate:self didFinishSelector:@selector(setAccessToken:withData:) didFailSelector:@selector(accessTokenTicket:didFailWithError:)];
[loadingOverlay setText:NSLocalizedString(@"Authorizing", nil)];
[loadingOverlay showAnimated:YES];
}
// If the token request fails, alert the user.
//
- (void)accessTokenTicket:(OAServiceTicket *)ticket didFailWithError:(NSError *) error {
[loadingOverlay hideAnimated:YES];
NSString *title = NSLocalizedString(@"Authorization Failed", nil);
NSString *message = NSLocalizedString(@"Check your username and password", nil);
NSString *cancelTitle = NSLocalizedString(@"Close", nil);
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:title message:message delegate:nil cancelButtonTitle:cancelTitle otherButtonTitles:nil];
[[alertView autorelease] show];
}
// If the token request succeeds, handle the response. (A successful HTTP request doesn't
// necessarily imply a token was successfully generated).
//
- (void)setAccessToken:(OAServiceTicket *)ticket withData:(NSData *)data {
if (!ticket.didSucceed || !data) {
[self accessTokenTicket:ticket didFailWithError:nil];
return;
}
NSString *dataString = [[[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding] autorelease];
if (!dataString) {
[self accessTokenTicket:ticket didFailWithError:nil];
return;
}
NSArray *dataStringComponents = [dataString componentsSeparatedByString:@"&"];
for(NSString *string in dataStringComponents) {
NSRange range = [string rangeOfString:@"oauth_token=" options:NSLiteralSearch];
if (range.location != NSNotFound) {
self.authToken = [string substringWithRange:NSMakeRange(range.location + range.length, [string length] - range.length)];
}
}
for(NSString *string in dataStringComponents) {
NSRange range = [string rangeOfString:@"oauth_token_secret=" options:NSLiteralSearch];
if (range.location != NSNotFound) {
self.authSecret = [string substringWithRange:NSMakeRange(range.location + range.length, [string length] - range.length)];
}
}
[loadingOverlay setText:NSLocalizedString(@"Saving", nil)];
[self saveToken];
}
// If a token was received, save it to the Gowalla server.
//
- (void)saveToken {
NSMutableDictionary *params = [NSMutableDictionary dictionary];
[params setObject:authToken forKey:@"token"];
[params setObject:authSecret forKey:@"secret"];
[AFHTTPRequest post:saveTokenURL params:params delegate:self successSelector:@selector(requestDidSucceed:)];
}
// If saving the token failed, alert the user
//
- (void)request:(AFHTTPRequest *)request didFailWithError:(NSError *)error {
[loadingOverlay hideAnimated:YES];
NSString *title = NSLocalizedString(@"Saving Failed", nil);
NSString *message = NSLocalizedString(@"Your authorization couldn’t be saved", nil);
NSString *cancelTitle = NSLocalizedString(@"Close", nil);
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:title message:message delegate:nil cancelButtonTitle:cancelTitle otherButtonTitles:nil];
[[alertView autorelease] show];
}
// If saving the token succeeded, return to the parent controller.
//
- (void)requestDidSucceed:(AFHTTPRequest *)request {
[loadingOverlay hideAnimated:YES];
[self.navigationController popViewControllerAnimated:YES];
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment