Coder Social home page Coder Social logo

Comments (3)

samskiter avatar samskiter commented on May 22, 2024

Having tried to use this to do twitter reverse-auth I now realise how non-standard their API is so i can see why you wouldn't want to.

from afoauth1client.

iwasrobbed avatar iwasrobbed commented on May 22, 2024

(Updated) @samskiter Here is a basic example of how to user AFOAuth1Client to do reverse auth (Gist located here: https://gist.github.com/iwasrobbed/9559783). Hope it helps 👍

How to use it:

// Try to get the tokens from their iOS native account by using reverse auth
[self performReverseAuthForAccount:account success:^(NSString *oauthToken, NSString *oauthSecret) {
  self.twitterClient.accessToken = [[AFOAuth1Token alloc] initWithKey:oauthToken secret:oauthSecret session:nil expiration:nil renewable:NO];
  if (successHandler) {
    successHandler(oauthToken, oauthSecret);
  }
} failure:^(NSString *errorMsg) {
  // Fall back to using Safari to authenticate
}];

Full code:

//
//  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

from afoauth1client.

mattt avatar mattt commented on May 22, 2024

Thanks, @iwasrobbed.

from afoauth1client.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.