2010年6月11日金曜日

JavaScriptのencodeURIComponentでハマる

珍しくWeb開発系の話。

奇特な動作方式(詳しくは過去エントリ参照)のTwitter
bot「カーチャンbot」のOAuth対応を行っていたとき、何を思ったか、OAuthをライブラリ等使わずに作ってみようと思いまして、あ、HMAC-SHA1とかbase64とかの部分以外は、ですが、んでいろいろやった過程で、ハマったことを書きたいと思います。
…って思ったけれど時間が経って何に悩んだのか忘れてしまったので、一番最近ハマったことを1つ。


JavaScriptの encodeURIComponentでは「-_.!~*'();/?:@&=+$,%#」といった文字のうち、

-_.!~*'()

がencodeされない、ということ。

これらのうち「!*'()」がOAuthを使ったAPIアクセスで問題に。まあTimeline取得やfavをやるにはこんな文字列使わないから問題ないんだけれど、statusの更新、いわゆるつぶやきの投稿時に、Tweet内容にこれらの文字列があった場合に、Signature違いますって言われてしまいます。

ので、Signature生成前に、この変換されないやつらのうち問題になる5文字はさらに個別にencodeしてあげないとダメでした。
-_.~はそのまんまでいいです。

例えばこんな感じのencodeURI拡張版作っておくとよいです。


function encodeURIextend(str){
str = encodeURIComponent(str);
str = str.replace(/\!/g, "%21");
str = str.replace(/\*/g, "%2A");
str = str.replace(/\'/g, "%27");
str = str.replace(/\(/g, "%28");
str = str.replace(/\)/g, "%29");
return str;
}


formのinput or textareaには生文字列でよくて、あくまでpost時のSignature計算に使うメッセージ、POST&https%3A%2F%2Fapi.twitter.com%2F(略)status=ここの値として設定するときに、拡張encodeURIしておく必要があるということです。

まあJavaScriptのOAuthライブラリ使えば、そんなことでハマらずに済みます。Sample*今見たら、まんまこの5文字対策がしてありました。

*下記Twitter developersのOAuth Librariesで紹介されてるもの:
http://dev.twitter.com/pages/oauth_libraries#javascript

稀に、こういう無駄な経験が将来役に立つこともあるんですが、まあ今回のはないかなw

0 件のコメント: