ssshttp://code.google.com/p/gtm-oauth/wiki/GTMOAuthIntroduction

GTMOAuthIntroduction
OAuth Controllers for iOS and Mac Apps
Featured
Updated Sep 25, 2011 by grobb...@google.com
Using the OAuth Controllers

* Using the OAuth Controllers
o Introduction
o Using the iOS and Mac OS X OAuth Controllers
o Adding the Controllers to Your Project
+ ARC Compatibility
+ System Requirements
o Signing In to Google Services
+ Using the Authentication Tokens
+ Retrieving Authorization from the Keychain
+ Signing Out
o Signing in to non-Google Services
+ Using the Authentication Tokens
+ Retrieving Authorization from the Keychain
+ Signing Out
+ Debugging Tips
* Design Notes
* Questions and Comments

Introduction

OAuth 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.
Using the iOS and Mac OS X OAuth Controllers

The OAuth controllers are useful for authenticating both to Google servers and to other services.

There are example iOS and Mac applications using the OAuth controllers in the library's Examples directory.

Controller methods with "Google" in the name are for use only with Google services.
Adding the Controllers to Your Project

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 and the command on the source checkout page. 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".
ARC Compatibility

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.
System Requirements

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.
Signing In to Google Services

To display a sign-in view, your iOS application makes these calls to push the view:

#import "GTMOAuthViewControllerTouch.h"

static NSString *const kAppServiceName = @”My Application: Google Contacts”;

NSString *scope = @"http://www.google.com/m8/feeds/"; // scope for Google Contacts API

GTMOAuthViewControllerTouch *viewController;
viewController = [[[GTMOAuthViewControllerTouch alloc] initWithScope:scope
language:nil
appServiceName:kAppServiceName
delegate:self
finishedSelector:@selector(viewController:finishedWithAuth:error:)] autorelease];
[[self navigationController] pushViewController:controller
animated:YES];

A Mac application would display sign-in as a sheet on the current window, like this:

#import "GTMOAuthWindowController.h"

GTMOAuthWindowController *windowController;
windowController = [[[GTMOAuthWindowController alloc] initWithScope:scope
language:nil
appServiceName:kAppServiceName
resourceBundle:nil] autorelease];
[controller signInSheetModalForWindow:currentWindow
delegate:self
finishedSelector:@selector(windowController:finishedWithAuth:error:)];

The scope is a string identifying what access is being requested. For access to more than one scope, separate the scopes with a space.

If your application uses the Google Data APIs Objective-C Client Library, it should get scopes from the service classes. For example, the scope of the Contacts API shown above is available as

scope = [GDataServiceGoogleContacts authorizationScope];

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.
Using the Authentication Tokens

If authentication succeeds, your application should retain the authentication object. It can be used directly to authorize NSMutableURLRequest objects:

[auth authorizeRequest:myNSURLMutableRequest]

In the Google Data APIs library the auth can be stored in a library service object to authorize future API requests:

[[self contactService] setAuthorizer:auth];

Retrieving Authorization from the Keychain

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:

GTMOAuthAuthentication *auth;
auth = [GTMOAuthViewControllerTouch authForGoogleFromKeychainForName:kAppServiceName];

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

Signing Out

To completely discard the user’s authorization, use the view or window controller calls to remove the keychain entry and to ask the Google server to revoke the token:

[GTMOAuthViewControllerTouch removeParamsFromKeychainForName:kAppServiceName];

[GTMOAuthViewControllerTouch revokeTokenForGoogleAuthentication:auth];

Finally, release the authorization object.
Signing in to non-Google Services

To sign in to a non-Google service (and some Google services), 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 controllers with services other than Google APIs, 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.
Using the Authentication Tokens

If authentication succeeds, your application should retain the authentication object. It can be used directly to authorize NSMutableURLRequest objects:

[auth authorizeRequest:myNSURLMutableRequest];

Retrieving Authorization from the Keychain

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

Signing Out

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.
Debugging Tips

Getting OAuth 1 to work with a service provider can be challenging. Here are a few times for getting GTMOAuth working.
HTTP Logging

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.
Signature Base String

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.
Design Notes

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.
Questions and Comments

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.
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值