AndroidネットワークのVolly+OkHttp+Https

9793 ワード

Vollyはもう長い間発表されました.広く応用されています.関連教程は至るところにあります.本論文では二つの注意すべきところを言います.
本論文の説明部分が少ないので、提供した関連リンクを参照してください. Github docat/Android Network Demo ここより鮮明に見えるかもしれません.
転送層としてOkHttpを使用して実現した.
Vollyデフォルトは、Androidシステムのバージョンに従って異なるHttp転送プロトコルを使用して実装され、Android 2.3以下ではApacheHttpStackを転送プロトコルとして使用し、3.0および以下ではHttpURLConnectionをトランスポート層プロトコルとして使用する(コメントでは正しい友達に感謝する).
OkHttpは他の実装に比べて以下のような利点がある.
  • はSPDYをサポートしており、同じホストに接続されているすべての要求が一つのsocketを共有することができます.
  • SPDYが利用できない場合、接続池を使用して要求の遅延を低減する.
  • は、GZIPを使用してダウンロードコンテンツを圧縮し、圧縮動作はユーザに透明である.
  • は、応答キャッシュを利用して、重複したネットワーク要求を回避する.
  • ネットワークに問題が発生した場合、OKHttpは依然として有効であり、一般的な接続問題から回復する.
  • あなたのサーバーに複数のIPアドレスがあると、最初のアドレスの接続に失敗したとき、OKHttpは他のアドレスへの接続を試みます.これはIPV 4とIPV 6と複数のデータセンターにホストされているサービスにとって非常に必要です.
  • その代わりにOkHttpを使うのが良いです.
  • は、まずOkHttpを用いて、Vollyのrequest Queを構築するための新しいHurlStackを実現する.
    public class OkHttpStack extends HurlStack {
    
     private OkHttpClient okHttpClient;
    
     /** * Create a OkHttpStack with default OkHttpClient. */
     public OkHttpStack() {
         this(new OkHttpClient());
     }
    
     /** * Create a OkHttpStack with a custom OkHttpClient * @param okHttpClient Custom OkHttpClient, NonNull */
     public OkHttpStack(OkHttpClient okHttpClient) {
         this.okHttpClient = okHttpClient;
     }
    
     @Override
     protected HttpURLConnection createConnection(URL url) throws IOException {
         OkUrlFactory okUrlFactory = new OkUrlFactory(okHttpClient);
         return okUrlFactory.open(url);
     }
    }
  • それからOkHttpStockを使って新しいVolly request Queを作成します.
    requestQueue = Volley.newRequestQueue(getContext(), new OkHttpStack());
    requestQueue.start();
    これでいいです.
  • Httpsを使う
        節操のある開発者として、Httpsを使ってユーザーのデータを保護するべきです.Android開発者のウェブサイトに掲載されたSecurity With HTTPS and SSLについて詳しく説明しました.OkHttp自身はHttpsをサポートしています.ドキュメントOkHttp Httpsを参考にして、上のOkHttpStackをそのまま使用すればいいですが、サーバー開発兄が署名した証明書を使っています.(なぜ自分でサインしたのか聞かないでください.)正常に訪問できなくなりました.
        ネット上では、何もしないTrustManagerSSLの検証をスキップするという案が多く提示されています.これは攻撃を受けやすく、Httpsも虚構のようです.
    私が採用したプランは署名した証明書をAPKに包装して信頼を加えることです.
    利点:
  • アプリケーションは逆方向に向かず、アプリケーションはもうシステムのtrust storeに依存しなくなり、Charesトラッピングなどのツールが失効します.アプリケーションAPIを分析するにはAPKを逆コンパイルしなければなりません.
  • 証明書を追加で買う必要がないので、お金を節約します.
    短所:
  • 証明書の配置の柔軟性が低下し、証明書を変更するとプログラムをアップグレードしなければならない.
    ステップを実行
    一番有名な自署名サイト12306を例に説明します.
  • 証明書を導出する
     echo | openssl s_client -connect kyfw.12306.cn:443 2>&1 |  sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p' > kyfw.12306.cn.pem
  • 証明書をbksフォーマットに変えて最新のbcprov-jdkをダウンロードし、以下のコマンドを実行します.storepassは鍵ファイルをエクスポートするパスワードです.
    keytool -importcert -v \  -trustcacerts \  -alias 0 \  -file <(openssl x509 -in kyfw.12306.cn.pem) \  -keystore $CERTSTORE -storetype BKS \  -providerclass org.bouncycastle.jce.provider.BouncyCastleProvider \  -providerpath ./bcprov-jdk16-1.46.jar \  -storepass asdfqaz
  • .導出したKfw.bksファイルをres/rawフォルダの下に入れる.
  • 作成SelfSignSslOkHttpStack
    /** * A HttpStack implement witch can verify specified self-signed certification. */
    public class SelfSignSslOkHttpStack extends HurlStack {
    
     private OkHttpClient okHttpClient;
    
     private Map<String, SSLSocketFactory> socketFactoryMap;
    
     /** * Create a OkHttpStack with default OkHttpClient. */
     public SelfSignSslOkHttpStack(Map<String, SSLSocketFactory> factoryMap) {
         this(new OkHttpClient(), factoryMap);
     }
    
     /** * Create a OkHttpStack with a custom OkHttpClient * @param okHttpClient Custom OkHttpClient, NonNull */
     public SelfSignSslOkHttpStack(OkHttpClient okHttpClient, Map<String, SSLSocketFactory> factoryMap) {
         this.okHttpClient = okHttpClient;
         this.socketFactoryMap = factoryMap;
     }
    
     @Override
     protected HttpURLConnection createConnection(URL url) throws IOException {
         if ("https".equals(url.getProtocol()) && socketFactoryMap.containsKey(url.getHost())) {
             HttpsURLConnection connection = (HttpsURLConnection) new OkUrlFactory(okHttpClient).open(url);
             connection.setSSLSocketFactory(socketFactoryMap.get(url.getHost()));
             return connection;
         } else {
             return  new OkUrlFactory(okHttpClient).open(url);
         }
     }
    }
  • は次にSelfSignSslOkHttpStackを用いてVollyのRequest Queを作成する.
     String[] hosts = {"kyfw.12306.cn"};
     int[] certRes = {R.raw.kyfw};
     String[] certPass = {"asdfqaz"};
     socketFactoryMap = new Hashtable<>(hosts.length);
    
     for (int i = 0; i < certRes.length; i++) {
         int res = certRes[i];
         String password = certPass[i];
         SSLSocketFactory sslSocketFactory = createSSLSocketFactory(context, res, password);
         socketFactoryMap.put(hosts[i], sslSocketFactory);
     }
    
     HurlStack stack = new SelfSignSslOkHttpStack(socketFactoryMap);
    
     requestQueue = Volley.newRequestQueue(context, stack);
     requestQueue.start();
  • 私達は試してみます.前の服のRequest Queを元のものに変えて、お願いします.
         StringRequest request = new StringRequest(
                 Request.Method.GET,
                 "https://kyfw.12306.cn/otn/",
                 new Response.Listener<String>() {
                     @Override
                     public void onResponse(String response) {
                         responseContentTextView.setText(response);
                     }
                 },
                 new Response.ErrorListener() {
                     @Override
                     public void onErrorResponse(VolleyError error) {
                         responseContentTextView.setText(error.toString());
                     }
                 });
         RequestManager.getInstance(this).addRequest(request, this);