VolleyがBasic Authで400返される事案の解消

メモ

Android 2.3.x において Volley 1.0.2 でベーシック認証つきリクエストを投げた際に、下記のように400を返されてしまって失敗する。同じコードでも Android 4.x では大丈夫っぽかった。

Volley﹕ [24] BasicNetwork.performRequest: Unexpected response code 400 for http://example.com/api/foo

ベーシック認証で Authorization: Basic ほにゃらら を渡すところを消したら、ちゃんと 401 が返ってきたので認証周りで何かおかしいと推測して調べた。

解決

てきとうにググってたら下記 Stack Overflow の投稿を参考に問題が解決できた。

String raw = String.format("%s:%s", BuildConfig.BASIC_AUTH_DARWIN_API_ID,
                BuildConfig.BASIC_AUTH_DARWIN_API_PASS);
return String.format("Basic %s", Base64.encodeToString(raw.getBytes(), Base64.DEFAULT));

Base64.encodeToString() の第二引数でフラグを渡しているが、これが DEFAULT だとマズかった。

String raw = String.format("%s:%s", BuildConfig.BASIC_AUTH_DARWIN_API_ID,
                BuildConfig.BASIC_AUTH_DARWIN_API_PASS);
return String.format("Basic %s", Base64.encodeToString(raw.getBytes(),
                Base64.URL_SAFE|Base64.NO_WRAP));

このように Base64.URL_SAFE|Base64.NO_WRAP を渡すとリクエストが成功するようになる。かるく試した限りだと、Base64.NO_WRAP だけでも大丈夫っぽいが念を入れて、参考元通りに2つともセットすることにした。

Base64.URL_SAFE

RFC 3548 section 4 に基づいて、URLおよびファイル名にして安全なエンコードを行うオプション。

Base64.NO_WRAP

エンコード結果に改行を含まれなくするオプション。

これがないと改行が入ってくるらしいが、Android 4.x で大丈夫だったというのは、根っこのほうのHTTPクライアントライブラリに、ヘッダから改行を除く処理が追加されているのかな?(HTTPヘッダインジェクション対策とか...)

参考