BDBOAuth1Manager is an OAuth 1.0a library for AFNetworking 2.x.
BDBOAuth1Manager consists of three core classes: BDBOAuth1RequestSerializer
, BDBOAuth1RequestOperationManger
, and BDBOAuth1SessionManager
. Below I will provide a quick overview of each, but to really see how the three classes work together, take a look at the included demo apps. One is a simple Twitter client and the other a simple Flickr photo gallery, but they show how to get started using BDBOAuth1Manager in your projects.
BDBOAuth1RequestOperationManger
is a subclass of AFHTTPRequestOperationManager
that provides methods to facilitate the OAuth 1 authentication flow.
@property (nonatomic) BDBOAuth1RequestSerializer *requestSerializer;
#pragma mark Initialization
- (instancetype)initWithBaseURL:(NSURL *)baseURL
consumerKey:(NSString *)consumerKey
consumerSecret:(NSString *)consumerSecret;
#pragma mark Authorization Status
@property (nonatomic, assign, readonly, getter = isAuthorized) BOOL authorized;
- (BOOL)deauthorize;
#pragma mark OAuth Handshake
- (void)fetchRequestTokenWithPath:(NSString *)requestPath
method:(NSString *)method
callbackURL:(NSURL *)callbackURL
scope:(NSString *)scope
success:(void (^)(BDBOAuth1Credential *requestToken))success
failure:(void (^)(NSError *error))failure;
- (void)fetchAccessTokenWithPath:(NSString *)accessPath
method:(NSString *)method
requestToken:(BDBOAuth1Credential *)requestToken
success:(void (^)(BDBOAuth1Credential *accessToken))success
failure:(void (^)(NSError *error))failure;
BDBOAuth1SessionManager
is a subclass of AFHTTPSessionManager
that has the same API as BDBOAuth1RequestOperationManger
, which is described above.
If your deployment target is either iOS 6 or OS X 10.8, you must use BDBOAuth1RequestOperationManger
, as the underlying NSURLSession
that is used by AFHTTPSessionManager
is a new addition to the iOS and OS X networking frameworks for iOS 7 and OS X 10.9.
BDBOAuth1RequestSerializer
is a subclass of AFHTTPRequestSerializer
that handles all the networking requests performed by BDBOAuth1RequestOperationManger
and BDBOAuth1SessionManager
. Both classes automatically handle the creation of this serializer, so you should never have to instantiate it on your own.
BDBOAuth1RequestSerializer
also has built-in support for storing and retrieving an OAuth access token to/from the user's keychain, utilizing the service name to differentiate tokens. BDBOAuth1RequestOperationManger
and BDBOAuth1SessionManager
automatically set the service name to baseURL.host (e.g. api.twitter.com) when they are instantiated.
The first step in performing the OAuth handshake is getting an OAuth request token for your application. This can be done with the fetchRequestTokenWithPath:method:callbackURL:scope:success:failure:
method.
[self.networkManager fetchRequestTokenWithPath:@"/oauth/request_token"
method:@"POST"
callbackURL:[NSURL URLWithString:@"bdboauth://request"]
scope:nil
success:^(BDBOAuth1Credential *requestToken) {
NSString *authURL = [NSString stringWithFormat:@"https://api.twitter.com/oauth/authorize?oauth_token=%@", requestToken.token];
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:authURL]];
}
failure:^(NSError *error) {
NSLog(@"Error: %@", error.localizedDescription);
}];
When calling fetchRequestTokenWithPath:method:callbackURL:scope:success:failure:
, you must provide a unique callback URL whose scheme corresponds to a URL type you've added to your project target. This allows the OAuth provider to return the user to your app after the user has authorized it. For example, if I add a URL type to my project with the scheme bdboauth
, my application would then respond to all URL requests that begin with bdboauth:
. If I pass bdboauth://request
as the callback URL, the OAuth provider would call that URL and my application would resume.
In order to respond to your application's URL scheme being called, you must implement the -application:openURL:sourceApplication:annotation
method within your application delegate. You can do something like this:
- (BOOL)application:(UIApplication *)application
openURL:(NSURL *)url
sourceApplication:(NSString *)sourceApplication
annotation:(id)annotation {
if ([url.scheme isEqualToString:@"bdboauth"]) {
if ([url.host isEqualToString:@"request"]) {
NSDictionary *parameters = [url dictionaryFromQueryString];
if (parameters[@"oauth_token"] && parameters[@"oauth_verifier"]) {
[self.networkManager fetchAccessTokenWithPath:@"/oauth/access_token"
method:@"POST"
requestToken:[BDBOAuth1Credential credentialWithQueryString:url.query]
success:^(BDBOAuth1Credential *accessToken) {
[self.networkManager.requestSerializer saveAccessToken:accessToken];
}];
}
}
return YES;
}
return NO;
}
BDBOAuth1Manager was created by Bradley David Bergeron and influenced by AFOAuth1Client. Both AFNetworking and AFOAuth1Client are the awesome work of Mattt Thompson.