2011年6月2日木曜日

Evernoteにアクセスする その2 OAuthアクセス編


前回サンプルを動作させてみました。
サンプルはOAuthの動作を見せる感じに作ってあります。
JSPに書かれていて処理がわかりずらいのでコードを解析しながら読みやすくしていきましょう。

最初の方は定数等を定義していますね。

private enum supportedRedirSchemas {FULL, EMBED};


は、iframeを利用する場合の処理の分岐ですね。
少し分かりづらいですが、基本的にindex.jspに対して、
「action」という引数を渡して処理を行ってます。


  1. getRequestTokenの処理

  2. Evernoteにアクセス(引数なし)

  3. 認証後getAccessTokenの処理

  4. AccessTokenによりlistNotebooks



という順序で処理を行っています。
これはRequestTokenを準備してEvernoteにアクセスして
認証結果をAccessTokenで取得。
最後にAPIにアクセスしている感じです。

まぁご存知「OAuth1.0」アクセスです。
まずはgetRequestTokenによるrequestTokenの取得です。

サンプルのはじめのリンクをクリックした時の処理


SimpleOAuthRequest oauthRequestor =
new SimpleOAuthRequest(requestTokenUrl, consumerKey, consumerSecret, null);

// Set the callback URL
String thisUrl = request.getRequestURL().toString();
 String cbUrl = thisUrl.substring(0, thisUrl.lastIndexOf('/') + 1);
 if (redirSchema != null && redirSchema.equals(supportedRedirSchemas.EMBED.toString())) {
  cbUrl = cbUrl + callbackEmbedUrl;
 } else {
  cbUrl = cbUrl + callbackUrl;
 }
 oauthRequestor.setParameter("oauth_callback", cbUrl);

out.println("Request: " + oauthRequestor.encode());
Map reply = oauthRequestor.sendRequest();
out.println("Reply: " + reply);
requestToken = reply.get("oauth_token");
session.setAttribute("requestToken", requestToken);


ここで大事なのは
 com.evernote.oauth.consumer.SimpleOAuthRequest
クラスです。

コンストラクタではリクエストする為の引数を作っています。
その後、iframe埋め込みかを判定して、戻ってくるURLを変更しています。
サンプルを動作させるとわかりますがEMBEDを選んだ場合はiframeが出現して、
callback.jspが表示され、そのiframe上で認証をかけます。
なのでまぁその辺はあまり関係ないです。(OAuth後に呼び出すURLを変更するだけ)

sendRequest()によりrequestTokenUrlにリクエストして、RequestTokenを取得しにいっています。
戻り値のマップはResponseの値です。


その下で取得したRequestTokenでURLを作成しています。


String authorizationUrl = authorizationUrlBase + "?oauth_token=" + requestToken;
if (redirSchema != null && redirSchema.equals(supportedRedirSchemas.EMBED.toString())) {
authorizationUrl = authorizationUrl + "&format=microclip";
}


埋め込みの場合は少しいじってますね。
このURL(Evernote)にアクセスする事で認可できるわけです。
このURLが2番目のURL。

JSPでまどろっこしいのですが、
基本的にはURL生成からリダイレクトすればいきなり認証も可能ですね。

そのURLにアクセスすれば



という風にEvernoteへの認可画面(認証済なのでこういう画面ですが認証してないとログイン画面)が出ます。

これに認可されると指定してあるCallbackUrlに処理がきます。

コールバックで戻ってくる最初の処理がこちら。


requestToken = request.getParameter("oauth_token");
verifier = request.getParameter("oauth_verifier");
session.setAttribute("verifier", verifier);


ちなみに「oauth_verifier」がnullの時は認可がされなかった時になります。
とにかくセッションに貯めてますね。。。このサンプル。
実際使う場合はコールバックURLでRequestTokenもverifierも取得して判定すれば良いでしょう。

で3番目のリンクをクリックすると


// Send an OAuth message to the Provider asking to exchange the
// existing Request Token for an Access Token
SimpleOAuthRequest oauthRequestor =
new SimpleOAuthRequest(requestTokenUrl, consumerKey, consumerSecret, null);
oauthRequestor.setParameter("oauth_token",
(String)session.getAttribute("requestToken"));
oauthRequestor.setParameter("oauth_verifier",
(String)session.getAttribute("verifier"));
out.println("Request: " + oauthRequestor.encode());
Map reply = oauthRequestor.sendRequest();
out.println("Reply: " + reply);
accessToken = reply.get("oauth_token");
String shardId = reply.get("edam_shard");
session.setAttribute("accessToken", accessToken);
session.setAttribute("shardId", shardId);


この処理を行っています。
再度SimpleOAuthRequestを利用してアクセストークンを取得しています。
・・・まぁセッションにまた貯めてますねぇ。。。

で最後にAPIにアクセスしています。


String noteStoreUrl = noteStoreUrlBase +
session.getAttribute("shardId");

out.println("Listing notebooks from: " + noteStoreUrl);
THttpClient noteStoreTrans = new THttpClient(noteStoreUrl);
TBinaryProtocol noteStoreProt = new TBinaryProtocol(noteStoreTrans);
NoteStore.Client noteStore =
new NoteStore.Client(noteStoreProt, noteStoreProt);
List notebooks = noteStore.listNotebooks(accessToken);

for (Object notebook : notebooks) {
out.println("Notebook: " + ((Notebook)notebook).getName());
}


これによりノートブック一覧が取得できます。
ひとまずOAuthアクセスはこんな感じでできます。

SimpleOAuthRequestを読んでもらえればわかりますが、
パラメータを設定してアクセスしてあげてくれるだけです。

なのでOAuthの仕組みさえわかっていれば簡単です。
※サンプルは流れさえ押さえれば、わかるのですが
 JSPだけでアクセスしてるのでかなり複雑な書き方になっています。

OAuth1.0の解説で一番わかりやすいのはゆろよろ氏が記述している
OAuthプロトコルの中身をざっくり解説してみるよだと思います。
ご覧になってください。


さて今回はサンプルを元にやりましたので
次回Slim3を使ってアクセスしてみましょう!

0 件のコメント: