[OAuth][mobile][socialapp][java] Shift-JISにおける「ミ」問題、%7E問題(signatureの検証に失敗するケース)
某GR社や某De社のモバイルソーシャルアプリ開発で詰まるポイントがあるようなので、まとめ。ただし、遭遇したケースについてのみなので、網羅性はありません。
事象
クライアント端末から送信されてくるformの内容に "%7E"(半角チルダ文字"~") が含まれているとき、oauth signatureの検証に失敗する。たとえばG社の場合、G社から送られてきているoauth signatureと、自サーバ側で生成したoauth signatureが異なってしまう、ということ。
⇒BaseStringの生成がおかしいのだろう
結論(急いでいる人のための結論)
BaseString生成時に "%7E" は "~" にunescapeしておく。たとえば カタカナの"ミ" は Shift-JISでは "%83%7E" で送信されてくるが、この部分だけをBaseString向けにエンコードすると "%2583~" となる、ということ。
詳細
今回、これを解決できたのは (TwitterID)chrno001さんのPOSTがあったからこそです。ありがとうございました!で、調べてみると、RFC5849の3.6. Percent Encodingに、
2. The values are then escaped using the [RFC3986] percent-encoding
(%XX) mechanism as follows:* Characters in the unreserved character set as defined by
[RFC3986], Section 2.3 (ALPHA, DIGIT, "-", ".", "_", "~") MUST
NOT be encoded.* All other characters MUST be encoded.
* The two hexadecimal characters used to represent encoded
characters MUST be uppercase.
つまり %7Eの "~" 以外にもエンコードしちゃいけない文字がある、と。注意しましょう。
RFC3986 2.3. Unreserved Charactersにも書いてあります。
RFC3986 compliantなエンコーダがあればいいのですが、今回のプロジェクトはJavaだったので、それについて少し調べてみた。
- java.net.URLEncoder はダメ (javadoc参照 ⇒ http://java.sun.com/javase/ja/6/docs/ja/api/java/net/URLEncoder.html)
- org.apache.commons.codec.net.URLCodec もダメ
そもそも、この2つのエンコーダは URL用エンコーダということで RFC3986準拠とは書いてませんね*1。
そのほか
Shift-JIS使うなよ、と言われてもG社から指定されているので仕方ありません。。。*1:これでいくと "*" もヤバそうだが...