Skip to content

Instantly share code, notes, and snippets.

@iwasrobbed
Last active August 29, 2015 13:57
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save iwasrobbed/9559783 to your computer and use it in GitHub Desktop.
Save iwasrobbed/9559783 to your computer and use it in GitHub Desktop.
Example of how to use AFOAuth1Client to do reverse auth of an ACAccount
//
// EvstReverseAuthExample.m
// Everest
//
// Created by Rob Phillips on 3/14/14.
//
#import <Accounts/Accounts.h>
#import "EvstReverseAuthExample.h"
#import "AFOAuth1Client.h"
static NSString *const kEvstTwitterBaseURL = @"https://api.twitter.com";
static NSString *const kEvstTwitterXAuthModeKey = @"x_auth_mode";
static NSString *const kEvstTwitterXAuthReverseParams = @"x_reverse_auth_parameters";
static NSString *const kEvstTwitterXAuthReverseTarget = @"x_reverse_auth_target";
static NSString *const kEvstTwitterReverseAuthKey = @"reverse_auth";
static NSString *const kEvstTwitterRequestTokenPath = @"/oauth/request_token";
static NSString *const kEvstTwitterAccessTokenPath = @"/oauth/access_token";
typedef void(^TwitterKeyPairHandler)(NSString *oauthToken, NSString *oauthSecret);
static NSString *const kEvstTwitterConsumerKey = @"CONSUMER_KEY"; // Don't share these in a public repo
static NSString *const kEvstTwitterConsumerSecretKey = @"CONSUMER_SECRET_KEY"; // Don't share these in a public repo
@interface EvstReverseAuthExample ()
@property (nonatomic, strong) AFOAuth1Client *twitterClient;
@end
@implementation EvstReverseAuthExample
#pragma mark - Singleton & Class Init
+ (instancetype)sharedInstance {
static id sharedInstance = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
sharedInstance = [[self alloc] init];
});
return sharedInstance;
}
- (instancetype)init {
if (self = [super init]) {
// Setup the Twitter OAuth1 client
self.twitterClient = [[AFOAuth1Client alloc] initWithBaseURL:[NSURL URLWithString:kEvstTwitterBaseURL]
key:kEvstTwitterConsumerKey
secret:kEvstTwitterConsumerSecretKey];
}
return self;
}
#pragma mark - Reverse Auth
// Note: The following was adapted from: https://github.com/seancook/TWReverseAuthExample
/*!
Performs reverse auth for the given account in order to exchange the iOS token for a verified Twitter access/secret token pair
\param account The @c ACAccount for which you wish to exchange tokens after being granted access by the user
*/
- (void)performReverseAuthForAccount:(ACAccount *)account success:(TwitterKeyPairHandler)successHandler failure:(void (^)(NSString *errorMsg))failureHandler {
NSParameterAssert(account);
[self getReverseAuthHeadersWithSuccess:^(NSString *signedReverseAuthSignature) {
[self exchangeTokensForAccount:account signature:signedReverseAuthSignature success:^(id responseData) {
NSString *responseString = [[NSString alloc] initWithData:responseData encoding:NSUTF8StringEncoding];
NSArray *components = [responseString componentsSeparatedByString:@"&"];
NSMutableDictionary *response = [[NSMutableDictionary alloc] initWithCapacity:components.count];
for (NSString *keyWithValueSeparatedByEqualSign in components) {
NSArray *keyWithValue = [keyWithValueSeparatedByEqualSign componentsSeparatedByString:@"="];
[response setValue:keyWithValue.lastObject forKeyPath:keyWithValue.firstObject];
}
NSString *oauthToken = [response objectForKey:@"oauth_token"];
NSString *oauthSecretToken = [response objectForKey:@"oauth_token_secret"];
NSLog(@"Received this data: %@ and %@", oauthToken, oauthSecretToken);
if (successHandler) {
successHandler(oauthToken, oauthSecretToken);
}
} failure:^(NSString *errorMsg) {
if (failureHandler) {
failureHandler(errorMsg);
}
}];
} failure:^(NSString *errorMsg) {
if (failureHandler) {
failureHandler(errorMsg);
}
}];
}
/*!
Step 1: In this step, we sign and send a request to Twitter to obtain an authorization header
*/
- (void)getReverseAuthHeadersWithSuccess:(void (^)(NSString *signedReverseAuthSignature))successHandler failure:(void (^)(NSString *errorMsg))failureHandler {
NSDictionary *parameters = @{kEvstTwitterXAuthModeKey : kEvstTwitterReverseAuthKey};
NSURLRequest *request = [self.twitterClient requestWithMethod:@"POST" path:kEvstTwitterRequestTokenPath parameters:parameters];
AFHTTPRequestOperation *operation = [self.twitterClient HTTPRequestOperationWithRequest:request success:^(AFHTTPRequestOperation *operation, id responseObject) {
if (successHandler) {
successHandler([[NSString alloc] initWithData:responseObject encoding:NSUTF8StringEncoding]);
}
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
if ([error code] != NSURLErrorCancelled && failureHandler) {
failureHandler(error.localizedDescription);
}
}];
[operation start];
}
/*!
Step 2: In this step, we send our signed authorization header to Twitter in a request that is signed by iOS
\param account The @c ACAccount for which you wish to exchange tokens
\param signedReverseAuthSignature The authorization header returned from Step 1
*/
- (void)exchangeTokensForAccount:(ACAccount *)account signature:(NSString *)signedReverseAuthSignature success:(void (^)(id responseData))successHandler failure:(void (^)(NSString *errorMsg))failureHandler {
NSParameterAssert(account);
NSParameterAssert(signedReverseAuthSignature);
NSDictionary *parameters = @{kEvstTwitterXAuthReverseParams : signedReverseAuthSignature,
kEvstTwitterXAuthReverseTarget : kEvstTwitterConsumerKey};
NSString *absolutePath = [NSString stringWithFormat:@"%@%@", kEvstTwitterBaseURL, kEvstTwitterAccessTokenPath];
SLRequest *slRequest = [SLRequest requestForServiceType:SLServiceTypeTwitter requestMethod:SLRequestMethodPOST URL:[NSURL URLWithString:absolutePath] parameters:parameters];
slRequest.account = account;
[slRequest performRequestWithHandler:^(NSData *responseData, NSHTTPURLResponse *urlResponse, NSError *error) {
if (error && [error code] != NSURLErrorCancelled && failureHandler) {
failureHandler(error.localizedDescription);
return;
}
successHandler(responseData);
}];
}
@end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment