&tag(GTMOAuth);
*目次 [#qea7a900]
#contents
*参考情報 [#t3892a5a]
-[[gtm-oauth - Google Toolbox for Mac - OAuth Controllers - Google Project Hosting:http://code.google.com/p/gtm-oauth/]]…Google製のOAuthライブラリ。
-[[GTMOAuthでTwitterなどのOAuthを行う方法 - Awaresoft:http://www.awaresoft.jp/ios-dev/item/90-gtmoauth]]
-[[予定外 [iOS5/ARC対応] iOSでTwitterクライアント その1 (準備編):http://homepie.blog.shinobi.jp/Entry/32/]]
-[[予定外 [iOS5/ARC対応] iOSでTwitterクライアント その2 (サインイン):http://homepie.blog.shinobi.jp/Entry/33/]]
-[[予定外 [iOS5/ARC対応] iOSでTwitterクライアント その3 (タイムライン取得):http://homepie.blog.shinobi.jp/Entry/34/]]
-[[予定外 [iOS5/ARC対応] iOSでTwitterクライアント その4 (ツイート投稿):http://homepie.blog.shinobi.jp/Entry/35/]]
*基本 [#x97244e3]
-TwitterのWebページをUIWebViewで表示しOAuth認証するライブラリ。
-OAuthするだけなので、Twitterでつぶやくとかそういう機能はない。

*サンプル: OAuthSampleTouch [#a5991874]

**基本 [#yd2b2ddb]
-GTMOAuthをダウンロードしたフォルダの中にある、OAuthSampleTouchというのがiOS用のサンプル。2012/07/24(火)現在のものなので将来的に変わる可能性あり。
-ビルドしてもそのまま動かないので、OAuthSampleRootViewControllerTouch.mを修正する。
-以下TwitterのOAuth認証を利用する場合の修正方法を説明。
-Twitterアプリは予めdev.twitter.comで登録しておく。認証タイプはBrowserにしておかないとだめ(コールバックURLにURLが入っているかどうかで判定しているらしい。つまりURLが入っていればBrowser。入ってなければデスクトップ扱い。)。
** OAuthSampleRootViewControllerTouch.mのauthForTwitterの修正 [#r81b0d6b]
-ConsumerKey, ConsumerSecretを自分のTwitterアプリのものに修正する(これはTwitterにアプリを登録すれば表示される)。
#pre{{
- (GTMOAuthAuthentication *)authForTwitter {

  //以下を修正
  NSString *myConsumerKey = @"YourConsumerKey";
  NSString *myConsumerSecret = @"YourConsumerSecret";

  if ([myConsumerKey length] == 0 || [myConsumerSecret length] == 0) {
    return nil;
  }

  GTMOAuthAuthentication *auth;
  auth = [[[GTMOAuthAuthentication alloc] initWithSignatureMethod:kGTMOAuthSignatureMethodHMAC_SHA1
                                                        consumerKey:myConsumerKey
                                                         privateKey:myConsumerSecret] autorelease];

  [auth setServiceProvider:kTwitterServiceName];

  return auth;
}
}}
**signInToTwitterの修正 [#jacafd5e]
-OAuthに必要なURLを修正する。変わる可能性があるのでTwitterアプリページに表示されるものをコピペしたほうがよい(httpじゃなくhttpsとか)。
-scopeはnilでいいらしい。
-setCallbackで設定するURLはダミーでいいらしい。
-setBrowserCookiesURLでセットするURLはブラウザのCookieを消去するURL。二回目表示したときにログイン状態にならないようにする。これもOAuthのURLに併せてhttpsバージョンにしたほうがいいっぽい。
#pre{{
- (void)signInToTwitter {

  [self signOut];

  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"];

  GTMOAuthAuthentication *auth = [self authForTwitter];
  if (auth == nil) {
    // perhaps display something friendlier in the UI?
    NSAssert(NO, @"A valid consumer key and consumer secret are required for signing in to Twitter");
  }

  //これはダミーでいいらしい
  [auth setCallback:@"http://www.example.com/OAuthCallback"];

  NSString *keychainItemName = nil;
  if ([self shouldSaveInKeychain]) {
    keychainItemName = kTwitterKeychainItemName;
  }

  // Display the autentication view.
  GTMOAuthViewControllerTouch *viewController;
  viewController = [[[GTMOAuthViewControllerTouch alloc] initWithScope:nil //scopeはNULLに
                language:nil
         requestTokenURL:requestURL
       authorizeTokenURL:authorizeURL
          accessTokenURL:accessURL
          authentication:auth
          appServiceName:keychainItemName
                delegate:self
        finishedSelector:@selector(viewController:finishedWithAuth:error:)] autorelease];

  // Cookieを消去するURLこれもhttpsバージョンにしたほうがよいのかな?
  [viewController setBrowserCookiesURL:[NSURL URLWithString:@"https://api.twitter.com/"]];
  [[self navigationController] pushViewController:viewController animated:YES];
}
}}


**動作確認 [#b8579aa4]
-Twitterを選び、[Sign In]ボタンを押す。
#ref(start.png)
-Twitterアカウントを入力。
#ref(twitter.png)
-AccessTokenが表示される。デバッガ出力に動作確認として認証が必要なステータスが出力される。
#ref(finish.png)

**動作の流れ解説 [#s24e0a6d]
***認証開始 [#t1690249]
-[Sign in]ボタンを押すとsignInOutClicked→signInToTwitterと呼ばれる。
-signInToTwitterでは、GTMOAuthViewControllerTouchが呼ばれる。このビューコントローラーはフレームワーク側にある。TwitterのWeb認証が行われる。
***認証成功 [#m952e8f4]
-Web認証が終わるとGTMOAuthSignIn.mのaccessFetcher:finishWithData:error:が呼ばれる。
#pre{{

- (void)accessFetcher:(GTMHTTPFetcher *)fetcher finishedWithData:(NSData *)data error:(NSError *)error {
  [self setPendingFetcher:nil fetchType:nil];

  if (error) {
    [self invokeFinalCallbackWithError:error];
  } else {
    // we have an access token
    [auth_ setKeysForResponseData:data];
    [auth_ setHasAccessToken:YES];

#if !GTM_OAUTH_SKIP_GOOGLE_SUPPORT
    if (shouldFetchGoogleUserInfo_
        && [[auth_ serviceProvider] isEqual:kGTMOAuthServiceProviderGoogle]) {
      // fetch the user's information from the Google server
      [self fetchGoogleUserInfo];
    } else {
      // we're not authorizing with Google, so we're done
      [self invokeFinalCallbackWithError:nil];
    }
#else
    [self invokeFinalCallbackWithError:nil];
#endif
  }
}
}}
-  [auth_ setKeysForResponseData:data]は、GTMOAuthAuthenticationのメソッドで_authオブジェクトに必要な情報がセットされる。
#pre{{
- (void)setKeysForResponseDictionary:(NSDictionary *)dict {
  NSString *token = [dict objectForKey:kOAuthTokenKey];
  if (token) {
    [self setToken:token];
  }
  
  NSString *secret = [dict objectForKey:kOAuthTokenSecretKey];
  if (secret) {
    [self setTokenSecret:secret];
  }
  
  NSString *callbackConfirmed = [dict objectForKey:kOAuthCallbackConfirmedKey];
  if (callbackConfirmed) {
    [self setCallbackConfirmed:callbackConfirmed];
  }
  
  NSString *verifier = [dict objectForKey:kOAuthVerifierKey];
  if (verifier) {
    [self setVerifier:verifier];
  }
  
  NSString *provider = [dict objectForKey:kServiceProviderKey];
  if (provider) {
    [self setServiceProvider:provider];
  }
  
  NSString *email = [dict objectForKey:kUserEmailKey];
  if (email) {
    [self setUserEmail:email];
  }
  
  NSString *verified = [dict objectForKey:kUserEmailIsVerifiedKey];
  if (verified) {
    [self setUserEmailIsVerified:verified];
  }
}
}}
-次にGTMOAuthSignIn.mのaccessFetcher:finishWithData:error:からGTMOAuthViewControllerTouchのsaveParamsToKeychainForNameが呼ばれ、認証情報がキーチェインに保存される。
#pre{{
+ (BOOL)saveParamsToKeychainForName:(NSString *)appServiceName
                     authentication:(GTMOAuthAuthentication *)auth {
  [self removeParamsFromKeychainForName:appServiceName];
  // don't save unless we have a token that can really authorize requests
  if (![auth hasAccessToken]) return NO;

  // make a response string containing the values we want to save
  NSString *password = [auth persistenceResponseString];
  GTMOAuthKeychain *keychain = [GTMOAuthKeychain defaultKeychain];
  return [keychain setPassword:password
                    forService:appServiceName
                       account:kGTLOAuthAccountName
                         error:nil];
}

}}
-最後に、GTMOAuthSignIn.mのaccessFetcher:finishWithData:error:から、viewController:finishedWithAuth:errorが呼ばれる。成功の場合doAnAuthenticatedAPIFetchが呼ばれ、そこでTwitterで認証されたアカウントのタイムラインがテスト用に表示される(出力ウィンドウに)。

***保存済みの認証情報の利用 [#nfac1dab]
-次のように初期化する。
-次のように初期化する。kTwitterKeychainItemNameは当然保存時に指定したキーチェイン名と同じにすること。
#pre{{
        _auth =  [[GTMOAuthAuthentication alloc] initWithSignatureMethod:kGTMOAuthSignatureMethodHMAC_SHA1
                                                             consumerKey:kTwitterConsumerKey
                                                              privateKey:kTwitterConsumerSecret];
        BOOL didAuth = [GTMOAuthViewControllerTouch authorizeFromKeychainForName:kTwitterKeychainItemName
                                                                  authentication:_auth];
        NSLog(@"didAuth=%d", didAuth);
}}
*自前のプロジェクトに組み込む [#j88b6a5d]
-Security.frameworkとSystemConfiguration.frameworkの追加が必要。
-GTMHTTPFetcherLogging.mでSBJsonを使っている。

トップ   編集 差分 履歴 添付 複製 名前変更 リロード   新規 一覧 検索 最終更新   ヘルプ   最終更新のRSS