OAuth 2.0 で YouTube Data API を使う

YouTube Data API ってご存知でしょうか。

 

https://developers.google.com/youtube/v3/

 

こちらにある通り、Google API のひとつで、YouTubeのコンテンツデータを取得するためのAPIです。

 

「人気の動画」や「検索ワードにヒットする動画」とかならそれぞれの URL に対して http の GET を行えば良いのですが、Googleアカウントに紐付いた情報(「後で見る」動画リスト、「お気に入り」動画リスト等)を取得するためにはGoogleアカウントの情報を取得する仕組みが必要です。その仕組も数種類あるのですが、そのうちのひとつが OAuth 2.0 というわけです。

 

本記事では、iOSアプリケーションからYouTube Data API を用いて、Googleアカウントに紐付いた情報を OAuth 2.0 を使って取得するまでの流れをご説明します。

 内容は下記の通り進めていきます。

 ■OAuth 2.0 とは

 ■Google API 使用準備

 ■OAuth 2.0 でアクセストークンを取得

 ■YouTube Data API で「後で見る」リスト取得

 

OAuth 2.0 とは

 スマホアプリ内で普通にアカウント情報を使用するとなると、ユーザーIDやパスワードを各アプリ内で入力してもらい、アプリ内で記憶する、といったことが必要になります。複数端末を使用されている方であれば、各端末の各アプリにそれぞれユーザーIDとパスワードを覚えさせる必要が出てきます。これは、セキュリティ上あまり安全とは言えません。

 OAuth 2.0では、ユーザーIDとパスワードの入力を受け取る部分はブラウザ(それが各アプリ内のWebビューなのか、ブラウザアプリなのかはさておき)に任せ、そこから得られたアクセストークンのみを各アプリ内で使用します。

 アクセストークンがあれば必要な情報は取れてしまうので、結局ユーザーIDとパスワードを覚えているのと変わらないのではないか、と思われる方もいらっしゃるでしょう。しかし、このアクセストークンは通常、有効期限がとても短く設定されています。なので、もし盗聴され、アクセストークンが漏洩してしまうような事態になっても、被害を最小に抑えることができます(有効期限が短いので切れるたびに「リフレッシュ」というアクセストークンを取り直す操作が必要になるのですが、それは後述)。

 

 以上が OAuth 2.0 の簡単な説明です。他のサイトには、もっと詳細に解説されているところもあるので調べてみて下さい。

 

Google API 使用準備

 Google API の使用には Google アカウントが必要です。まだ持っていない方は登録して下さい。

 さて、以下のサイトにアクセスしていただくと Google apis コンソールが開きます。まだプロジェクトを作成されていない場合は Other projects→Create…にて新規にプロジェクト作成を行います。

f:id:kfurue:20130819075147p:plainhttps://developers.google.com/accounts/docs/OAuth2?hl=ja

 

 その後、Servicesタブを選択し、その中にある YouTube Data API v3 をONにします。

f:id:kfurue:20130819075107p:plain

 

 次に、API Accessタブを選び、Create an OAuth 2.0 client ID…を押します。

f:id:kfurue:20130819075307p:plain

 必須項目はプロダクト名だけなので、好きなプロダクト名を入力してNext。

 ここでクライアントIDの設定をします。iOS アプリケーション内から使用しますので、Application type は Installed application、Installed application type は iOS を選択します。Bundle ID か App Store ID のどちらかが必須となります。まだ App Store に後悔されていないアプリでしたら、Bundle ID を入力しておきましょう。Create client ID を押せばClient ID などが表示され、準備完了です。

 

f:id:kfurue:20130819075354p:plain

OAuth 2.0 でアクセストークンを取得

 では、ここから Xcode に移って実際にアプリ内から API を使用してみましょう。

 これには以下手順が必要です。

 ○Google の authorization server に接続し、authorization code を取得

 ○authorization code を含むリクエストを所定の URL に POST し、アクセストークンとリフレッシュトークンを取得

 

では順番に見ていきましょう。

 

Google の authorization server に接続し、authorization code を取得

 Google の authorization server は以下になります。

 https://accounts.google.com/o/oauth2/auth

 

 リクエストパラメーターに必要な物は下記の通り。

 

client_id:APIs Console に表示されているもの

redirect_uri:APIs Console に表示されているもの

response_type:「code」に固定

scope:取得するアクセストークンの権限

state:必須ではない。設定しておけば authorization code と一緒に返ってくる

 

 以下は Google のサイトに掲載されている例です。

 https://accounts.google.com/o/oauth2/auth?

  client_id=1084945748469-eg34imk572gdhu83gj5p0an9fut6urp5.apps.googleusercontent.com&

  redirect_uri=http%3A%2F%2Flocalhost%2Foauth2callback&

  scope=https://www.googleapis.com/auth/youtube&

  response_type=code&

  access_type=offline

 

 

  

  access_type って何でしょう?w 説明が無いのでわかりません。また折を見て調べてみることにします。

  

  さて、ここで困るのがリダイレクト URI です。Safari などのブラウザアプリに飛ばして、ユーザーにIDとパスワードを入力してもらい、URLスキーム使って自アプリにリダイレクト、とかできるのかなと思ったのですが、残念ながら APIs Console に表示される Redirect URIs は

  urn:ietf:wg:oauth:2.0:oob

  http://localhost

  のどちらかしかありません。

  

  両パターン指定して実行してみると、それぞれ下図のようになります。

f:id:kfurue:20130819075451p:plain

 

f:id:kfurue:20130819075508p:plain

  どちらをもちいてもとりあえず authorization code を取ることはできるのですが、見た目上、urn:~ のほうがよろしい気がするのでこっちでやってみます。localhost を指定してまともに動かしたければ local web server 立てなくてはいけなくなりますもんね。

  

  で、urn:~ を指定して実行すると、ご覧のように authorization code が表示され、ユーザー操作によってコピペしてもらえればアプリ側で取得可能、というわけです。これなら Safari なんかのブラウザアプリ内でやってもらうことも可能ですね。自アプリから Safari に飛ばし、そこで Google アカウントにログインしてもらって Google APIs によるアクセス許可をユーザー操作によって承認してもらう。表示された authorization code をユーザーにコピーしてもらい、ユーザー操作で自アプリに戻ってきてもらって貼り付けてもらうことで無事取得、というわけです。

  

authorization code を含むリクエストを所定の URL に POST し、アクセストークンとリフレッシュトークンを取得

 それではいよいよアクセストークンの取得です。先ほど取れた authorization code を使用します。

 POST 先は以下になります。

 https://accounts.google.com/o/oauth2/token

 

  以下が Google のサイトに乗っているリクエストのサンプルです。

POST /o/oauth2/token HTTP/1.1

Host: accounts.google.com

Content-Type: application/x-www-form-urlencoded

 

code=4/ux5gNj-_mIu4DOD_gNZdjX9EtOFf&

client_id=1084945748469-eg34imk572gdhu83gj5p0an9fut6urp5.apps.googleusercontent.com&

client_secret=hDBmMRhz7eJRsM9Z2q1oFBSe&

redirect_uri=http://localhost/oa

 

 

  

  雑ですが、iOS で実装するとこんなかんじでしょうか。self.authorizationCode に先ほど取得した authorization code が入っているとします。

    NSMutableURLRequest *req = [NSMutableURLRequest requestWithURL:

                                [NSURL URLWithString:@"https://accounts.google.com/o/oauth2/token"]

                                                       cachePolicy:NSURLRequestReloadIgnoringCacheData timeoutInterval:60];

    NSString *bodyString = [self.authorizationCode stringByAppendingString:@"&"

                            "client_id=hogehoge&" // ご自身の Client ID を入れて下さい

                            "client_secret=fugafuga&" // 同じくご自身の Client secret を

                            "redirect_uri=urn:ietf:wg:oauth:2.0:oob&"

                            "grant_type=authorization_code"];

    NSData *bodyData = [bodyString dataUsingEncoding:NSUTF8StringEncoding];

    [req setValue:@"application/x-www-form-urlencoded"                 forHTTPHeaderField:@"Content-Type"];

    [req setValue:[NSString stringWithFormat:@"%d", [bodyData length]] forHTTPHeaderField:@"Content-Length"];

 

    [req setHTTPMethod:@"POST"];

    [req setHTTPBody:bodyData];

    self.connection = [[NSURLConnection alloc] initWithRequest:req delegate:self];

 

  NSURLConnectionDataDelegate メソッドの didReceiveData で待っていると response としてアクセストークン、リフレッシュトークンを含む JSON データを受け取ることができます。

  以下サンプル。

 

{

  "access_token" : "ya29.AHES6ZTtm7SuokEB-RGtbBty9IIlNiP9-eNMMQKtXdMP3sfjL1Fc",

  "token_type" : "Bearer",

  "expires_in" : 3600,

  "refresh_token" : "1/HKSmLFXzqP0leUihZp2xUt3-5wkU7Gmu2Os_eBnzw74"

}

 

 

 なんかユーザーにいろいろ操作させるのも忍びないので、無理くりですが可能な限り自動化してみた例を以下に置きました。

 

https://github.com/kfurue/SampleCodes/tree/master/OAuthTest 

 

 とりあえずここまで、続きはまた今度。