-
Notifications
You must be signed in to change notification settings - Fork 22
Home
OAuth 1 is a protocol allowing your application to obtain authorization to read or modify a user’s files or data on an external server.
The server generates a web page for the user to sign in with her name and password, including a button explicitly granting access to some of her data. Upon successful authentication, the server gives a token to your application representing the user's authorization.
With the Objective-C OAuth controllers, the web page can be presented as an iOS view or a Mac sheet within your application. The controllers also provide authentication objects that simplify your application's future requests for the user's data.
OAuth 1 relies on a fragile and complex request-signing process, and so is generally being supplanted by the newer OAuth 2 standard.
The OAuth controllers are useful for authenticating to a variety of services which require OAuth 1.
There are example iOS and Mac applications using the OAuth controllers in the library's Examples directory.
The project has targets for building a static library for iOS and a framework for Mac OS X. Alternatively, the source files and xibs may be dragged directly into your project file and compiled with your application.
Check out the "top-of-trunk" OAuth controller sources with a Mac terminal window. The source files required are:
iOS and Mac OS X | iOS | Mac OS X |
---|---|---|
GTMOAuthAuthentication.h/m GTMOAuthSignIn.h/m GTMHTTPFetcher.h/m | GTMOAuthViewControllerTouch.h/m GTMOAuthViewTouch.xib (optional) | GTMOAuthWindowController.h/m GTMOAuthWindow.xib |
These source files can be browsed in the project's source directory.
When linking against a static library build of the controller, specify the -ObjC build option for the application target's "Other Linker Flags".
When the controller source files are compiled directly into a project that has ARC enabled, then ARC must be disabled specifically for the controller source files.
To disable ARC for source files in Xcode 4, select the project and the target
in Xcode. Under the target "Build Phases" tab, expand the Compile Sources build
phase, select the library source files, then press Enter to open an edit field,
and type -fno-objc-arc
as the compiler flag for those files.
The Mac controller is compatible with Mac OS X 10.5 and later. The iOS controller is compatible with iPhone OS 3 and later.
The OAuth controllers require linking to the system frameworks Security.framework and SystemConfiguration.framework.
To sign in to a service, you should consult the service's API documentation to obtain a pre-assigned consumer key and secret string, and to find the required scope string for API operations.
To use the OAuth 1 controllers with services, your application should create an authentication object with the appropriate keys, like this:
- (GTMOAuthAuthentication *)myCustomAuth {
NSString *myConsumerKey = @"abcd"; // pre-registered with service
NSString *myConsumerSecret = @"efgh"; // pre-assigned by service
GTMOAuthAuthentication *auth;
auth = [[[GTMOAuthAuthentication alloc] initWithSignatureMethod:kGTMOAuthSignatureMethodHMAC_SHA1
consumerKey:myConsumerKey
privateKey:myConsumerSecret] autorelease];
// setting the service name lets us inspect the auth object later to know
// what service it is for
auth.serviceProvider = @"Custom Auth Service";
return auth;
}
Displaying the sign-in view with a custom auth also requires providing the OAuth endpoints (URLs) and scope string to the controller, as shown here:
- (void)signInToCustomService {
NSURL *requestURL = [NSURL URLWithString:@"http://example.com/oauth/request_token"];
NSURL *accessURL = [NSURL URLWithString:@"http://example.com/oauth/access_token"];
NSURL *authorizeURL = [NSURL URLWithString:@"http://example.com/oauth/authorize"];
NSString *scope = @"http://example.com/scope";
GTMOAuthAuthentication *auth = [self myCustomAuth];
// set the callback URL to which the site should redirect, and for which
// the OAuth controller should look to determine when sign-in has
// finished or been canceled
//
// This URL does not need to be for an actual web page
[auth setCallback:@"http://www.example.com/OAuthCallback"];
// Display the autentication view
GTMOAuthViewControllerTouch *viewController;
viewController = [[[GTMOAuthViewControllerTouch alloc] initWithScope:scope
language:nil
requestTokenURL:requestURL
authorizeTokenURL:authorizeURL
accessTokenURL:accessURL
authentication:auth
appServiceName:@"My App: Custom Service"
delegate:self
finishedSelector:@selector(viewController:finishedWithAuth:error:)] autorelease];
[[self navigationController] pushViewController:viewController
animated:YES];
}
The application service name is used to save the token on the user’s keychain, and should identify both your application name and the service name(s). If appServiceName is nil, the token will not be saved, and the user will have to sign in again the next time the application is run.
When the user signs in successfully or cancels signing in, the view or window controller will invoke your finishedSelector’s method:
- (void)viewController:(GTMOAuthViewControllerTouch *)viewController
finishedWithAuth:(GTMOAuthAuthentication *)auth
error:(NSError *)error {
if (error != nil) {
// Authentication failed
} else {
// Authentication succeeded
}
}
If [error code]
is kGTMOAuthErrorWindowClosed
(-1000), then the user closed
the sign-in view before completing authorization. Otherwise, any error reflects
the server response in validating the user's access.
The controllers also support Objective-C block completion handlers as alternatives to the delegate and finished selectors.
If authentication succeeds, your application should retain the authentication object. It can be used directly to authorize NSMutableURLRequest objects:
[auth authorizeRequest:myNSURLMutableRequest];
If your application saves the authorization to the keychain (by setting the controller's appServiceName), it can be retrieved the next time the application launches:
- (void)awakeFromNib {
// Get the saved authentication, if any, from the keychain.
GTMOAuthAuthentication *auth = [self myCustomAuth];
if (auth) {
BOOL didAuth = [GTMOAuthViewControllerTouch authorizeFromKeychainForName:@"My App: Custom Service"
authentication:auth];
// if the auth object contains an access token, didAuth is now true
}
// retain the authentication object, which holds the auth tokens
//
// we can determine later if the auth object contains an access token
// by calling its -canAuthorize method
[self setAuthentication:auth];
}
If no authorization was saved, then “auth” will still be a valid authorization object but will be unable to authorize requests:
BOOL isSignedIn = [auth canAuthorize]; // returns NO if auth cannot authorize requests
To completely discard the user’s authorization, use the view or window controller calls to remove the keychain entry:
[GTMOAuthViewControllerTouch removeParamsFromKeychainForName:kAppServiceName];
Finally, release the authorization object.
Getting OAuth 1 to work with a service provider can be challenging, especially with providers that implement extensions to the basic standard protocol. Here are a few times for getting GTMOAuth working.
Turn on http logging to inspect the server requests and responses. To enable
http logging, add GTMHTTPFetcherLogging.h/m
to your project, and call
[GTMHTTPFetcher setLoggingEnabled:YES];
The log will be written to a folder on the desktop or in the device data directory. Often, helpful server errors can be found in the responses in the log.
More information about http logging is in the GTMHTTPFetcher
documentation
here.
If the server signature check is failing, turn on signature diagnostics by specifying
#define GTL_DEBUG_OAUTH_SIGNING 1
at the top of GTMOAuthAuthentication.m
. The console output will then list the
components being signed and, more importantly, the base string being signed for
a sign-in attempt.
Compare the GTMOAuth base string to the base string shown in the provider's documentation.
The library's classes are designed in three layers.
Window/View Controller :: user interface & application API
Sign-In :: networking (OAuth dance)
Authentication :: data handling, request signing, and keychain
Classes are written to be independent of the layers above them.
The window and view controllers are retained only during the user's sign-in interaction.
The sign-in object is typically invisible to the client application.
The authentication object must be retained by the client app to sign
NSMutableURLRequests
. It is also used to save authentication to and read
authentication from the keychain.
You can learn more about the OAuth protocol for desktop and mobile applications at Google's documentation.
Additional documentation for the controllers is available in the header files.
If you have any questions or comments about the library or this documentation, please join the discussion group.