2011年 2月 07日(月曜日) 12:54

GTMOAuthでTwitterなどのOAuthを行う方法

評価:
(1 Vote)

facebookやTwitter、GoogleDataAPIなど、APIを公開しているサービスを利用するときに、OAuthを使うことが多くなってきました。OAuthをきちんと理解して使うのは結構たいへんな印象ですが、ライブラリを使うと手軽に利用できてしまいます。

ライブラリにもいろいろありますが、私が試した中では、かなりきちんとOAuthを理解していないと使うのが難しいようなライブラリもあるなかで、Google Toolbox for Mac - OAuth Controllers (GTMOAuth)は使い方が非常に簡単で、ほんの数行のコードを追加するだけで、自分のアプリケーションでOAuth認証が必要なサービスを利用することができます。

ただ、いくつか注意しなければならないことがあったので、使い方をメモしておきます。

0.利用したいサービスにアプリケーション登録

あらかじめ、利用したいサービスに自分のアプリケーションを登録しておきます。Twitterならこちらから。

ここで、Consumer key、Consumer secretや各種APIのURLを取得します。

Twitterで気をつけなければならないかったのは、Application TypeでClientではなくBrowserの方を選択しなければうまくいかなかったところ。(実際はClientなのですが。)GTMOAuthではブラウザアプリケーションで認証完了後に呼ばれるCallback URLをnilにすることができず、常に送信してしまうのですが、どうやらTwitterの方でClientを選択したにもかかわらずCallback URLが送られてくるとアクセスを拒否してしまうみたいです。これはかなりハマりました。

1.GTMOAuthのソースコードをダウンロード

gtm-oauthのGoogleCodeからsvnでソースコードをダウンロードします。Macではデフォルトでsvnコマンドが入っているので、コマンドラインから実行するのがいちばん簡単です。

2.ソースコードを自分のプロジェクトにコピー&フレームワークの追加

ダウンロードした中にXCodeのプロジェクトファイルも含まれているので、これを開いてスタティックライブラリをビルドして取り込むこともできますが、iOS SDKのバージョンが違って修正に苦労したり、コードサインの問題もあったり、付属しているViewControllerをちょっと変更したくなったりしたので、この方法はやめました。

次のような感じで、必要なソースコードのファイルを自分のプロジェクトに取り込みます。(コピーしても参照でもよいです。)HTTPFetcherはGTMOAuthの内部で使われるので必要になります。

gtm-oauth-sources

さらに、Security.frameworkとSystemConfiguration.frameworkをプロジェクトのFrameworksに追加します。

3.GTMOAuthAuthenticationオブジェクトの作成

Googleサービス以外のサービスにアクセスするときには、GTMOAuthAuthenticationのインスタンスをつくります。ConsumerKeyとConsumerSecretは、アクセスするサービスにアプリケーション登録したときに割り当てられたものを使います。

- (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;
}

4.GTMOAuthViewControllerを表示

OAuth認証を行うソースファイルで、GTMOAuthViewControllerTouch.hをインポートして、認証がひつようになるタイミングで、ViewControllerのインスタンスをつくって表示します。

下はTwitterにログインするメソッドの例。

Request URLやAccess URLなどは、Twitterにアプリケーション登録したときに表示されたものを使います。appServiceNameは自分で名前をつけます。

"scope"はたぶんGoogleDataAPI用なので使われていないので適当で大丈夫です。

下の例では、モーダルビューを表示して、ユーザに「許可」「拒否」を選んでもらう例のOAuth画面を表示します。そこでの手続き(OAuth danceっていうらしい)は全てGTMOAuthがやってくれます。:)

- (void)signInWithAuth:(GTMOAuthAuthentication *)auth {
    NSURL *requestURL = [NSURL URLWithString:@"https://api.twitter.com/oauth/request_token"];
    NSURL *accessURL = [NSURL URLWithString:@"https://api.twitter.com/oauth/access_token"];
    NSURL *authorizeURL = [NSURL URLWithString:@"https://api.twitter.com/oauth/authorize"];
    NSString *scope = @"http://api.twitter.com/oauth/request_token";
    
    auth.serviceProvider = @"Twitter";
    
    [auth setCallback:SIMPLE_WEIGHT_WEB_SITE_TOP];
    
    // Display the autentication view
    GTMOAuthViewControllerTouch *viewController;
    viewController = [[[GTMOAuthViewControllerTouch alloc] initWithScope:scope
                                                                language:nil
                                                         requestTokenURL:requestURL
                                                       authorizeTokenURL:authorizeURL
                                                          accessTokenURL:accessURL
                                                          authentication:auth
                                                          appServiceName:@"TwitterTestClientService"
                                                                delegate:self
                                                        finishedSelector:@selector(viewController:finishedWithAuth:error:)] autorelease];
    
    [self presentModalViewController:viewController animated:YES];
}

5.OAuth認証後に呼ばれるdelegateメソッドを実装

上でfinishedSelectorに設定したメソッドを実装します。OAuthが完了したときに呼ばれます。

- (void)viewController:(GTMOAuthViewControllerTouch *)viewController
      finishedWithAuth:(GTMOAuthAuthentication *)auth
                 error:(NSError *)error {
    if (error != nil) {
        // 認証に失敗したときの処理
    } else {
        // 認証に成功したときの処理
    }
    [self dismissModalViewControllerAnimated:YES];
}

6.認証されたAuthオブジェクトを使って、サービスにアクセスする

ここまでで認証は完了して、サービスにアクセスする準備ができました。あとは、普通にCocoa TouchでHTTP GET/POSTリクエストを送る方法を使って通信します。リクエストを送る前に、AuthオブジェクトのauthorizeRequest:を呼んで、リクエストにOAuth認証用のデータを付加します。

下のコードはTwitterに投稿する例。

- (void)postToTwitter:(GTMOAuthAuthentication *)auth {
    NSURL *url = [NSURL URLWithString:@"http://api.twitter.com/1/statuses/update.xml"];
    NSString *content = @"status=てすてぃんぐなう。";
    NSData *body = [content dataUsingEncoding:NSUTF8StringEncoding];
    NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL: url]; 
    [request setHTTPMethod: @"POST"];
    [request setValue:@"application/x-www-form-urlencoded" forHTTPHeaderField:@"content-type"];
    [request setHTTPBody: body];

    [auth authorizeRequest:request];
    
    NSURLConnection *conn = [NSURLConnection connectionWithRequest:request delegate:self];
    if (conn) {
        buffer = [[NSMutableData data] retain];
    } else {
        // エラー処理
    }
}

実際に使うときは送信する前にデータのURLエンコーディングなどが必要。こちらのページが参考になりました。

7.次回以降起動時に、Key ChainからAuthデータを読み込む

一度OAuth認証が完了すると、Access Tokenの期限が切れるまではAccess Tokenを使い回せます。GTMOAuthは認証情報をサービス名毎にちゃんとKeyChainに安全に保存してくれるのでとても便利です。

下はViewDidAppearでKeyChainから認証情報を読み込んでAuthオブジェクトに付加している例。

- (void)viewDidAppear:(BOOL)animated {
    GTMOAuthAuthentication *auth = [self myCustomAuth];
    BOOL didAuth = [GTMOAuthViewControllerTouch authorizeFromKeychainForName:@"TwitterTestClientService"
                                                              authentication:auth];
    if (!didAuth) {
        [self signIn];
    } else {
        // 認証後の処理
    }
}

もうOAuthを恐れることはありません。facebookやTwitterを使った新しいサービスをガンガンつくっていきましょう。

おまけ:OAuthの基礎が日本語でわかりやすく説明された記事がありました。これはわかりやすい。^^ライブラリを使う場合でも中でどんなことをしているかは知っておいた方がよいですね。

最終更新日: 2011年 6月 27日(月曜日) 01:10
くらち たかよし

くらち たかよし

モバイル・Webアプリ作家。最近は主にiPhoneアプリ制作を手がける。企画、UIデザイン、設計、実装、テストなどを1人〜数人の個人で行う全人的開発手法の確立を目指している。

使う言語はObjective-C, C++, C#, Java, PHPなど。Web関連で使うものはCakePHP, MySQL, Joomla! CMSなど。デザインではPhotoshopとIllustratorをかろうじて使う。

場所や時間に縛られない、インターネット時代の新しい働き方、自由な生き方を模索中。海外移住、低予算&低リスク起業、キャリアデザイン、心理学などにも興味あり。

Web: awaresoft.jp/