前回、Titaniumを使ってGAE上の認証を通すことを書きましたが、どうも、500のレスポンスが帰ってこなくなるだけで、必要なデータがとれていなかったようなので、再度確認しました。前回の奴は嘘です。忘れて下さい。
GAEアプリでなく、Google側の認証でエラーが発生しているので、ログを確認しようにもできません。ローカル環境で確認したところ、AndroidとiOSでリクエストヘッダは違いこそありますが、根本的に違うわけでは無さそうでした。*1
Client認証を行い、その結果をパラメータとしてURLに直接設定してブラウザを叩くと通ります。当然のことながら認証成功時に含まれる文字列を変更すると、エラーが返って来ます。iOSで帰ってくる500の画面と同じです。
私のコードはsendメソッドにリクエストパラメータを渡していましたが、URLに直接設定してみると・・・通りました。
うーん、httpの時は、GETでsendメソッドの引数にパラメータを設定することで送れていることは確認できたのですが、httpsだとダメ・・・なんでしょうかね?
よくわからないけど試してみたら動いた、という気持ち悪い結果になりましたが、TitaniumでiOS用のソースコードを記述する時は、https通信を行う場合、GETリクエストはURLに書いたほうがよさそうです。
ソースは以下の感じ。
//GAEに対するログイン //Googleに対してClient認証を行い、その結果をauthTokenに設定 function loginAppEngine(loginParam, authToken) { var appid = loginParam.appid; var baseUrl = "https://" + appid + ".appspot.com/"; var xhr = null; if(Ti.Platform.osname === 'android') { xhr = Titanium.Network.createHTTPClient(); } else { //iOSの場合、SSLチェックを緩くする xhr = Titanium.Network.createHTTPClient({ validatesSecureCertificate: false, tlsVersion: Titanium.Network.TLS_VERSION_1_0 }); } var query = "?continue=" + baseUrl + "&auth=" + authToken; var url = baseUrl + "_ah/login"; //POSTだとAndroidでもiOSでも500エラーが返るので、GETメソッドでないといけない xhr.open('GET',url + query); //レスポンスを受け取った際のイベント xhr.onload = function(){ indicator.hide(); //以降、ごにょごにょする }; // エラー発生時のイベント xhr.onerror = function(error){ indicator.hide(); //以降、ごにょごにょする }; //リクエスト送信 var indicator = Ti.UI.createActivityIndicator({ message : "Loading..." }); indicator.show(); xhr.send(); }
で、レスポンスヘッダからCookieに設定されているJSESSIONIDをGAEアプリへのリクエストに含めることで、AndroidでもiOSでも認証が必要なGAEアプリからJSONデータを取ってくることができます。
Titanium SDK 2.0.2だからなのか、そもそもだったのかわかりませんが、Androidで動作してiOSで動作しない時はこの辺りを疑ってもいいかもしれません。こんなにハマるとは思わんかった・・・。
*1:ConnectionがcloseだったりKeep-Aliveだったりの差はありましたが、確認した所、このお陰でエラーになっているわけではありませんでした