bit.ly の OAuth 2.0 とか色々試してみたら色々アレだった - にぽたん研究所

April 21, 2011

このエントリーをはてなブックマークに追加
ある日、うちのサービスで bit.ly 使って URL を短縮したいねーなんて話があがって、まぁ、単純に短縮化するなら、@shiba_yu36 さん作の WebService::Bitly なんか使えば簡単に色々出来て便利だなーって思いました。

で、きっと、このモジュールを使っているであろうはてなダイアリーとか見てみたら、bit.ly の設定画面があるんですね。

はてダの bit.ly 設定

自分自身の bit.ly アカウントを使えば bit.ly でトラッキングとか出来るし便利だなーと思いました。

…でもね、うちのサービスの利用者の方々は、はてな民のようなリテラシーの高いユーザばかりではないのですよ。
「bit.ly の API キー」とか言っても「は?????」って感じの方が大多数。
意味わからないものを設定画面につけるとなっちゃん宛にクレームがいっぱい来てしまいます。

とりあえず、bitly API Documentation を読んでみたら
bitly currently supports the OAuth 2 draft specification.
なんて書いてあって、どうも昨年 9 月中旬から OAuth 2.0 対応がなされた模様。
OAuth を使えば、web からのフローだけで、ユーザに API キーなんか入力させる必要がなかったりするので、こっちのほうがユーザさんにも使いやすいだろうと思ったのでした。
もっと言えば、実は、このたび bit.ly で URL を短縮させつつ、Facebook に更新情報を投稿する機能をつけたりしたので、「Twitter も OAuth (1.0) だし、同じフローのほうが使いやすそう。Facebook も OAuth (2.0) なんだから、ついで bit.ly も OAuth に対応させちゃえばいいかも!」なーんて、軽いノリで提案してみた。


…のが運の尽き。


Facebook の OAuth 対応等のネタはネット上のそこらじゅうで見受けられるが、bit.ly で OAuth 2.0 に対応したなんてマニアックな話ほとんど目にしないので、かなりの手探り状態から始まりました。

今日は、そんな思い出話を書こうと思います。




OAuth アプリの利用申請



当然まずは OAuth を使用するアプリを申請しなくてはいけませんね。

でも、bit.ly は Facebook なんかと違って、開発者向けサイトから辿って、フォームから簡単にアプリを登録出来たりなんかしません

bitly API Documentation にもあるように、
To request OAuth access, e-mail api@bit.ly with your bitly username.
メールで「OAuth やりたいです」ってお願いしなくちゃいけない。もちろん英語で。

とりあえず、こんなメールを送ってみたのです。
Subject: OAuth について

ビットリーさんこんにちは。

ちょっと我々がやってるブログサービスで、Twitter みたいなタイムラインに乗せる URL を短縮させたりで、OAuth を使いたいんだよね。
OAuth クライアントとして登録してもらえないですか?

ユーザ名は "○○○" です。

よろしくおねがいします。

(※ 送ったメールの意訳)
3/11 にこんなメールを送ったら、すぐに返事がもらえることを期待していたら、返事ではなく大地震がきてしまい、会社は出勤制限状態になり、bit.ly がどうのとか悠長なことを言っていられる状況ではなくなってしまいました。

で、大地震とか一切関係なく、bit.ly からの返事は待てどくらせどやって来ず、完全放置されてしまいました

出勤制限が解かれた 3/28 にも改めてメールを送りました。
Subject: OAuth 登録リクエスト

親愛なる bit.ly API 担当者様

我々がやってるブログサービスで、OAuth を使うことを計画しています。
client_id と client_secret の割り当てをお願いします。

こちらが我々のアカウント情報です:

bit.ly ユーザ名: ○○○
bit.ly API キー: X_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

宜しくお願いします。

(※ 送ったメールの意訳)
「こんなに放置されるなんて、もしかして bit.ly の担当者がイラっとしたのかなぁ…」なんて気になっていたので、今回はちょっと丁寧にしてみました。

しかしながら 10 日ほど経過してもレスがなく完全放置は続くよどこまでも

最初のメールから早一ヶ月近く経とうとしている頃、改めてメールをしました。
Subject: OAuth 登録リクエスト

親愛なる bit.ly API 担当者様

我々が開発している web アプリケーションを bit.ly OAuth クライアントで登録していただけることを願っております。
どうか client_id と client_secret の割り当てをお願い出来ませんでしょうか。
もしこのリクエストが却下されるとしたら、貴方がたから我々に対し、登録不可能として取り扱った明確な理由を教えてもらえると非常に助かります。
これは 3 回目の OAuth リクエストとなります。
「またリクエストがシカトされたなー」と、それに気付くまでずっとただ待ち続けるような時間的余裕はありません。

こちらが我々のアカウント情報です:

bit.ly ユーザ名: ○○○
bit.ly API キー: X_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

宜しくお願いします。

(※ 送ったメールの意訳)
ものすごく丁寧に、ちょっと半ギレ気味に嫌味を織り交ぜつつ食い下がってみました。
でもこういう丁寧に嫌味を言うのって、日本人には通じそうですが、英語圏の人にそういうのって通じるの?

…って心配していたら、それから 6 時間後に、ねんがんの ビットリーからのへんじを てにいれたぞ!

待ってました。いや、ホントに。
Subject: Re: OAuth 登録リクエスト

やぁ、公一、

連絡ありがとう!あなたのこれまでのメールに対して、全然返信しなかったことを、心の底からお詫びします。これは我々の部署の不注意であって、故意に無視したというわけではないです。

ただいまより、あなたの bitly アカウント設定画面で、OAuth アプリケーションの登録が出来るようになりましたよ。 何かご質問、または bitly にて OAuth を使用する上での懸念事項がある場合は、教えてください。合わせて、今後は速やかに返事をすることをここにお約束します

ご盛運を願います。
マット

(※ 送られてきたメールの意訳)
お詫びを含んでるんだから、「親愛なるミスタータニグチ様」ぐらいのことを言って欲しかったけれど、そこは流石のマット、いきなりファーストネームで語りかけ、場を和ませるという高度なテクニックを披露してくれ、挙句マットは「もうほったらかしなんてしないよ!」って約束してくれました。
この俺の半ギレのおかげで bit.ly の業務改善に一役買いました

まぁ、正直、「インターネットに普通にメアド晒してるんだから SPAM だらけだろうしマトモなメールもきっと見落とすだろうな」とか思ってました。
そして、このエントリ上にもメアドを拡散させたわけから、これが SPAM 業者に加担してしまう可能性が高いのは言うまでもない。

ということで、ようやくスタートラインに立ちました。。。
実に長い幕開けです。


OAuth アプリの登録



bit.ly からの返事メールをもらうと、それ以降アカウント設定の画面に、"Register OAuth Application" というリンクが登場します。 このリンクを押すと、アプリ登録フォームが登場します。

OAuth アプリ登録フォーム

ここで注目すべきは
NOTE: all redirect_uri values for this application must start with this URL.
OAuth 2.0 の場合、ユーザがアプリケーションを許可 (もしくは拒否) した場合、code パラメータ付きで帰ってくる URI を、redirect_uri パラメータで OAuth エンドポイントに対して access_token 取得時に渡す必要がありますが、それが「このフォームに登録する URL と前方一致してないとダメよ」ということみたいです。
これは OAuth 2.0 の仕様的には
The authorization server SHOULD require the client to pre-register their redirection URI or at least certain components such as the scheme, host, port and path. If a redirection URI was registered, the authorization server MUST compare any redirection URI received at the authorization endpoint with the registered URI.
と、正しいですが、「登録された URI と前方一致してないといけない」なんてことは書いてないですが、まぁとは言っても仕様として正しいし、bit.ly がそういう風に決めてるんだから、サブドメインを利用するサービスは死ねるということを知らないでアプリを開発してしまうともう悲劇です。
livedoor Blog というサービス自体、ブログの設定画面とかの URL がサブドメインで複数のブログサービスとして運用されているので、死にました
しかも、設定画面から別ウィンドウで OAuth をして、認証後に window.opener に対して、ログイン情報を書き換えるとかやってるんですけど、サブドメインがついてる URL → window.open('サブドメインがついてない URL') とかやったら、当然 window.opener はドメイン違うので不可侵領域になりますよね…。そんなこんなでエラい苦労しました。

ちなみに Facebook の場合は以下のような感じで Site Domain という設定でドメイン指定が出来るため、サブドメインでの運用も問題なく利用出来ます。

Facebook アプリ設定画面

bit.ly にもこれをやって欲しかったですね。


OAuth アプリ登録の際の注意点



実は、bit.ly の OAuth アプリ登録に、こんなにも注意点が多いなんてちっとも気付きませんでした。

● 一度登録したアプリは二度と編集出来ない



これは今までの web の常識を覆す、まさかの「編集フォームなし」です。

Registered OAuth Applications

どう見ても編集するリンクはありません。 登録する時にアプリ名を typo してしまったり、「あ、やっぱドメイン変えよう」とか思っても、一度登録してしまったら二度と引き返せないという恐怖が味わえます。
まぁ、ぶっちゃけ、間違ったら、また別のアプリとして登録すればいいじゃん?とか賢明なかたはお気付きのことかと存じます。

● 同じアプリ名は登録出来ない

他人であろうが自分であろうが、OAuth アプリとして登録されているアプリの名前はユニークなようで、上記要因で「失敗した!もう一個登録しよう!」とか思っても、submit したら Application Name Unavailable というエラーが表示され、その名前じゃ登録させんよ!って怒られてしまいます。
なら、どうすりゃいいのさ…。
ベストの解は、登録時は慎重に
これ以上の方法はないでしょう。

「二度と編集出来ない」なんて情報、知らなきゃカジュアルに失敗を犯しますけど、ここに情報を記すことで被害者が沢山出現しないことを願っています。
ちなみに俺はそんなこと何も知らなかったので、もちろんカジュアルに失敗しましたよ

● 3 つのアプリを登録したら登録出来ない



一度登録したら二度と編集出来ないんだし、「失敗した!もう一個登録しよう!」って、名前とかもウマい具合に工夫してアプリを増やすことで問題が回避出来ると考えるのは自然の流れ。
Facebook の場合、たくさんアプリを登録する場合に SMS を受け取るかクレジットカード番号を入れることなどで、複数のアプリを登録することを認めていますが、bit.ly の場合は違います。
3 つのアプリを登録したら、それまで Registered OAuth Applications のパラグラフの最下部にあった "Register OAuth Application" のリンクが突如として消えてしまいます

私は、無尽蔵に増やせるもんだと思って、2 個ほど失敗アプリを登録した後、3 個目にやっと開発環境用のアプリを正しく登録出来て喜んでいました。
しかし、喜んだのも束の間、リンクが消えて

「うわ!本番用のアプリ登録出来ないじゃん!どうすりゃいいのさ!またアカウント取って、bit.ly に OAuth 登録してってメールのやり取りをしないといけないの?!これ無理じゃね?!」

そう、私は完全なるパニック状態に陥ってしまったのです。

しかし、ありとあらゆる方法を考える中で、「ブラウザの履歴から、もう一度登録フォームの URL を開いたらどうなる?」と、恐る恐る開いてみました。
そう、無尽蔵にアプリを増やすための入口こんなところにあったのです…。

しかし、もちろん「表示されてないリンクの URL を叩いたら出来た」という裏技でしかないので、当然ながら推奨されてないでしょう。削除されてしまっても文句は言えないかも知れません。

やっぱり、登録時は慎重にとしか言いようがありません。

とりあえず、こんなに問題点があるので、知らないでカジュアルに失敗するより、このエントリを読んだ上で、慎重に行動されるのが吉だと思います。

一応、自分の場合はパニックに陥るまで一切慎重になりませんでした。まさかアプリ情報が編集出来ない、登録数に制限がある、名前がユニークだなんて思ってもみませんでしたから。ええ。。

OAuth アプリの実装



さてさて、問題点が解消したところで、アプリの実装ですが、@lyokato さん作の OAuth::Lite2 にある OAuth::Lite2::Client::WebServer を使えば、SYNOPSIS にある通りのほぼそのまんまな感じで簡単に実装出来る…と言いたかったのですが、bit.ly の Access Token Response が返す Content-Type から OAuth::Lite2::Formatters が formatter を断定出来ないという問題が発生し、access_token が取得出来ない問題が発生します。
ちなみに、bit.ly が返す Content-Type は text/html で、中身は application/x-www-form-urlencoded なもの。
Facebook はこれを text/plain で返すので、ひろせさんが Facebook 用に足したやつを書いてpull request を送って、OAuth::Lite2 の 0.01_06 以降で対応されました。
じゃあ bit.ly 用に text/html なやつを…なんて思って fork して pull req するかなーなんて考えたんですが、bit.ly の Content-Type がアレすぎるのと、そもそも、こんなに苦労してまで bit.ly の OAuth やりたい奴とか今のとこ俺ぐらいしかいないだろww とか思ってしまった瞬間完全に萎えてしまって、fork したまでで止まってしまいました。。。

とりあえず、
package OAuth::Lite2::Formatter::TextHTML;

use strict;
use parent qw(OAuth::Lite2::Formatter::FormURLEncoded);
sub type { "text/html" }

package OAuth::Lite2::Formatters;

__PACKAGE__->add_formatter(OAuth::Lite2::Formatter::TextHTML->new);
こんな超 BK っぽいおまじないで対応できるとおもいます。

ちなみに、短縮させるだけなら access_token 自体はいらないです。
my $access_token = $client->get_access_token(
    code         => $code,
    redirect_uri => q{http://yourapp/callback},
) or return $your_app->error($client->errstr);
$app->store->save(login   => $access_token->{login});
$app->store->save(api_key => $access_token->{apiKey});
こんな感じで保存したものを
use strict;
use warnings;
use WebService::Bitly;

my $bitly = WebService::Bitly->new(
    user_name        => 'nipotan',
    user_api_key     => 'R_1234567890abcdefg',
    end_user_name    => $app->store->login,
    end_user_api_key => $app->store->api_key,
);
my $shorten = $bitly->shorten('http://example.com/');
みたいにして、WebService::Bitly の end_user_* の値で利用します。

独自ドメインの対応



とりあえず、bit.ly は無料の PRO アカウントでも、独自ドメインが使えたりします。
PRO の申請は OAuth と違い、フォームから行なえますが、申請した後の画面で「承認されるまで 1 週間ぐらいかかるよ」的なことを言われます。実際は 4、5 日程度でしたが、PRO に昇格されるのは即座ではないことを念頭に置いておかないと、仕事の納期とかに響きますので要注意です。

晴れて PRO に昇格したら、Custom Short Domain を設定し、そのドメインの A レコードを bit.ly が指定する IP アドレスに向ければ、いよいよ独自短縮 URL が生成されます。


以上、とってもアレゲな bit.ly の OAuth および API ですが、案外サクサク動いていて快適です。

bit.ly の OAuth 対応をお考えの方は是非これらを参考にしてみてください。

cf. 短縮URLおよびbit.ly連携機能リリースしました



nipotan at 19:06 | Comments(0)
このエントリーをはてなブックマークに追加

Post a comment

Name:
URL:
  Remember info?: Rate: Face    Star