Titanium.Network.HTTPClientを使ってGAEの認証を通す(その2)

前回、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だったりの差はありましたが、確認した所、このお陰でエラーになっているわけではありませんでした