最近Unityの記事ばかり書いている大橋です。
今回はhttps通信です。
結論
この記事で言いたい事を先に言ってしまうと、
BestHTTPを使えばTLS1.2でhttps通信ができる!、、です。
UnityではWWWクラスがあるけれど
Unityでサーバーとhttp/https通信したいときは、WWWクラスを利用することでとても簡単に通信することができます。
けれども、WWWクラスは簡単に通信機能を実装できる反面、
いろんなものが隠蔽されていて、かゆいところに手が届かないのがネックです。
(かゆいところどころではない気が若干しますが……)
.Netのものを直接使えばいいじゃない
そういうことで、もっと手の込んだことをしたい場合は、WWWクラスを放り投げ、
.Netに標準搭載されているクラスを使って実装することになります。
その場合、https通信をしたいときは、System.Net.Security.SslStreamクラスなどを使ったりします。
ですが、さらにそこに落とし穴が!!
TLS1.1やTLS1.2でhttps通信できない
UnityでSslStreamクラスを使って実装すると、
TLS1.1やTLS1.2でhttps通信できません。
できるだけ強いセキュリティが必要な場合は、これは少し困ります。
この原因は、Unityが.Net 3.5準拠であることによります。
.Net 4.5であればTLS1.2を選択することができるのですが、
.Net 3.5ではTLS1.1、TLS1.2は選択できず、TLS1.0までしかありません。
TLS1.0ではセキュリティ的にやや不安が残ります。
BestHTTPがあるじゃないか!
ところがなんと、BestHTTPというAssetを導入すれば、TLS1.2でhttps通信ができるようです。
BestHTTP(Pro Edition)はAssetStoreで$55(2015/11/5現在セールで$24.75!)で購入できます。
やや値が張りますが、中身を鑑みれば、自分としては納得の値段。
使い方
なにはともあれusingです。
using BestHTTP;
リクエストを生成します。
OnRequestFinishedはサーバーからレスポンスが返ってきたときのコールバックです。これは後ほど。
System.Uri uri = new System.Uri (“https://example.com"); HTTPRequest bestHttpRequest = new HTTPRequest (uri, HTTPMethods.Post, OnRequestFinished);
必要に応じてヘッダーをセットします。
bestHttpRequest.AddHeader (“HeaderKey”, “HeaderValue”);
そして送信。
bestHttpRequest.Send ();
次に、リクエスト生成時に指定した、レスポンスが返ってきたときの処理です。
基本的には、HTTPRequest.StateとHTTPResponse.StatusCodeから結果を判断して、
それに応じた処理をします。
private void OnRequestFinished(HTTPRequest request, HTTPResponse response) { // request.Stateを見てリクエストが成功したかなどを判別します switch (request.State) { case HTTPRequestStates.Finished: // サーバーからレスポンスが返ってきたらHTTPRequestStates.Finishedになります。 // response.StatusCodeにレスポンスのステータスコードが入ってるので、値に応じた処理を行います。 if (response.StatusCode < 400) { // 成功時の処理 } else { // 失敗時の処理 } break; case HTTPRequestStates.Error: // 予期しないエラー break; case HTTPRequestStates.Aborted: // リクエストをHTTPRequest.Abort()でAbortさせた場合 break; case HTTPRequestStates.ConnectionTimedOut: // サーバーとのコネクションのタイムアウト break; case HTTPRequestStates.TimedOut: // リクエストのタイムアウト break; default: break; } }
実はこのままではTLS1.2で通信できません。
どうやらデフォルトではBestHTTPの内部でSystem.Net.Security.SslStreamを使っているようです。
そこで、HTTPManager.UseAlternateSSLDefaultValueをtrueに設定します。
これは、初めに1回だけ設定しておけば大丈夫です。
これによりTLS1.2で通信できるようになります。
HTTPManager.UseAlternateSSLDefaultValue = true;