Think Big Act Local

iPhone開発を軸にブレブレの記事を書いていきます。

Yahoo!Japanの認証機能であるYConnectをiPhoneアプリから試してみる

YConnectとはYahoo!Japanの提供するOAuth2.0に準拠した認証形式です。

例えばヤフーオークションのAPIであるユーザが入札中の商品一覧を取得したい時など、
ユーザ認証をする場面でYConnectの必要が出てきます。

公式サイトにも説明はありますが、残念ながらAndroidの例のみとなっています。
そこで今回は、iOSでYConnect認証を行う方法をまとめます。

アプリケーションの登録

とにもかくにも、まずはアプリケーションの登録を行いましょう。YahooIDが必要です。
今回はiPhoneアプリを考えていますので、「クライアントサイド」を選択します。

認証のフロー(Implicitフロー)

実装に入る前に、認証の流れについて大まかに把握しておきましょう。
YConnectの認証フローはAuthorization codeフローとImplicitフローとが用意されています。今回はImplicitフローで実装します。

  1. 認証URLを作成し、UIWebViewでloadRequestする
  2. Yahoo!のログイン画面が表示されるので、YahooIDとパスワードを入力してログイン
  3. 同意画面が表示されるので、「同意する」を選択
  4. redirect_uriパラメータで指定したURLに遷移する
    この時、URLパラメータとしてaccess_tokenなどの値が渡されます。
  5. UIWebViewでこのURLパラメータをパースし、アクセストークンを取得

このアクセストークンを使うことで認証が必要なAPIを利用することができます。
では、上記の手順を順番に実装していきましょう。

UIWebViewで認証画面を表示する

以下のページを参考に認証URLを作成します。
Authorizationエンドポイント - Yahoo!デベロッパーネットワーク

認証URLの例

https://auth.login.yahoo.co.jp/yconnect/v1/authorization?
response_type=token+id_token&client_id=<アプリケーションID>&state=xyz
&redirect_uri=http://yahuoku.herokuapp.com
&scope=openid+profile&nonce=ef3a091928d5491624c0ac54d697124422705091

注意:redirect_uriは任意の値でOKですが、アプリケーション登録情報の「コールバックURL」と一致していないとエラーが出ます。

リクエストパラメータの説明(一部を抜粋)

パラメータ 必須 説明
response_type token固定。id_tokenを求める際はスペース区切りで連結
client_id 登録時に発行されたアプリケーションID
redirect_uri アプリケーション登録時に設定したURLを指定
state コールバック時にこの値を乗せて返ってくる
display 表示テンプレを選択(page/touch/wap)
nonce リクエスト毎にランダムな文字列を指定

認証画面をリクエス

認証画面をUIWebViewで表示するには次のようにします。

// 認証画面をロード
NSString *urlStr = AUTH_URL; // 上記のURL
NSURL *url = [NSURL URLWithString:urlStr];
NSURLRequest *req = [[NSURLRequest alloc] initWithURL:url];
[self.webView loadRequest:req];

表示された認証画面で「同意する」を選ぶとリダイレクトで指定したURLに遷移します。

UIWebViewでフックをかけ、access_tokenを取得

リダイレクトされた際、URLにはURLパラメータが付属しています。
これをパースすることで"access_token"を取得することができます。

// 読込完了
- (void)webViewDidFinishLoad:(UIWebView *)webView {
  // パラメータのパース処理
  NSString *paramStr = webView.request.URL.fragment;
  NSDictionary *param = [self exposeQuery:paramStr];

  NSLog(@"access_token[%@]", [param objectForKey:@"access_token"]);
}

// hoge=123&fuga=abc  ->  [hoge->123, fuga->abc]
- (NSDictionary*)exposeQuery:(NSString*)query {
  NSMutableDictionary *dict = @{}.mutableCopy;
  NSArray *params = [query componentsSeparatedByString:@"&"];
  
  for (NSString *param in params) {
    NSArray *pArray = [param componentsSeparatedByString:@"="];
    if ([pArray count] == 2) {
      [dict setObject:pArray[1] forKey:pArray[0]];
    }
  }  
  return [NSDictionary dictionaryWithDictionary:dict];
}

webViewDidFinishLoadはUIWebViewDelegateのデリゲートメソッドで、ページの読込が完了したタイミングで呼ばれます。
上記のコードでは読込完了時にURLパラメータをパースし、key-valueの形で取得しています。

ここまでの処理が成功していれば、コンソールにaccess_tokenが表示されるはずです。
後は認証が必要なAPIにこのaccess_tokenを使ってアクセスすればOKです。

おわりに

以上、YConnect認証をiOSから行う方法でした。
OAuth認証の仕組みは様々なサービスで使われているので、しっかり理解したい所。
iOSSDK、早く出て欲しいですね。

参考リンク

関連書籍

iPhoneアプリ開発入門に超おすすめの一冊。
説明がとても丁寧でとっつきにくいObjective-Cの文法も理解できます。

記事に間違いなどあれば @himara2までお願いしますm