2016-01-07 93 views
2

我通過OKHttpClient帖子以用戶身份登錄,我想與webview共享cookie。OkHTTPClient將Cookie傳遞給Webview

+0

和你的問題是?如果是「我該怎麼做?」,那太寬泛了。如果它是「我在哪裏找到一個教程來做到這一點?」,那也將被關閉。你有特定的問題嗎? – njzk2

+0

儘管這裏的簡短描述問題很明顯,但是由此重複:http://stackoverflow.com/questions/7610790/add-custom-headers-to-webview-resource-requests-android – Than

回答

9

隨着OkHttp 3.0,你可以使用類似於通過使使用WebKit的cookie存儲一個WebkitCookieManagerProxy與HttpURLConnection的共享方法。改編自Pass cookies from HttpURLConnection (java.net.CookieManager) to WebView (android.webkit.CookieManager)

public class WebkitCookieManagerProxy extends CookieManager implements CookieJar { 
    private android.webkit.CookieManager webkitCookieManager; 

    private static final String TAG = WebkitCookieManagerProxy.class.getSimpleName(); 

    public WebkitCookieManagerProxy() { 
     this(null, null); 
    } 

    WebkitCookieManagerProxy(CookieStore store, CookiePolicy cookiePolicy) { 
     super(null, cookiePolicy); 
     this.webkitCookieManager = android.webkit.CookieManager.getInstance(); 
    } 

    @Override 
    public void put(URI uri, Map<String, List<String>> responseHeaders) 
      throws IOException { 
     // make sure our args are valid 
     if ((uri == null) || (responseHeaders == null)) 
      return; 

     // save our url once 
     String url = uri.toString(); 

     // go over the headers 
     for (String headerKey : responseHeaders.keySet()) { 
      // ignore headers which aren't cookie related 
      if ((headerKey == null) 
        || !(headerKey.equalsIgnoreCase("Set-Cookie2") || headerKey 
          .equalsIgnoreCase("Set-Cookie"))) 
       continue; 

      // process each of the headers 
      for (String headerValue : responseHeaders.get(headerKey)) { 
       webkitCookieManager.setCookie(url, headerValue); 
      } 
     } 
    } 

    @Override 
    public Map<String, List<String>> get(URI uri, 
      Map<String, List<String>> requestHeaders) throws IOException { 
     // make sure our args are valid 
     if ((uri == null) || (requestHeaders == null)) 
      throw new IllegalArgumentException("Argument is null"); 

     // save our url once 
     String url = uri.toString(); 

     // prepare our response 
     Map<String, List<String>> res = new java.util.HashMap<String, List<String>>(); 

     // get the cookie 
     String cookie = webkitCookieManager.getCookie(url); 

     // return it 
     if (cookie != null) { 
      res.put("Cookie", Arrays.asList(cookie)); 
     } 

     return res; 
    } 

    @Override 
    public CookieStore getCookieStore() { 
     // we don't want anyone to work with this cookie store directly 
     throw new UnsupportedOperationException(); 
    } 

    @Override 
    public void saveFromResponse(HttpUrl url, List<Cookie> cookies) { 
     HashMap<String, List<String>> generatedResponseHeaders = new HashMap<>(); 
     ArrayList<String> cookiesList = new ArrayList<>(); 
     for(Cookie c: cookies) { 
      // toString correctly generates a normal cookie string 
      cookiesList.add(c.toString()); 
     } 

     generatedResponseHeaders.put("Set-Cookie", cookiesList); 
     try { 
      put(url.uri(), generatedResponseHeaders); 
     } catch (IOException e) { 
      Log.e(TAG, "Error adding cookies through okhttp", e); 
     } 
    } 
} 
    @Override 
    public List<Cookie> loadForRequest(HttpUrl url) { 
     ArrayList<Cookie> cookieArrayList = new ArrayList<>(); 
     try { 
      Map<String, List<String>> cookieList = get(url.uri(), new HashMap<String, List<String>>()); 
      // Format here looks like: "Cookie":["cookie1=val1;cookie2=val2;"] 
      for (List<String> ls : cookieList.values()) { 
       for (String s: ls) { 
        String[] cookies = s.split(";"); 
        for (String cookie : cookies) { 
         Cookie c = Cookie.parse(url, cookie); 
         cookieArrayList.add(c); 
        } 
       } 
      } 
     } catch (IOException e) { 
      Log.e(TAG, "error making cookie!", e); 
     } 
     return cookieArrayList; 
    } 

然後在構建OkHttpClient時添加代理的實例作爲cookieJar。

client = new OkHttpClient.Builder().cookieJar(proxy).build(); 
+0

這很好用!謝謝! –

+1

如何將以上內容與PersistentCookieStore一起使用https://stackoverflow.com/a/34886860/3286489? – Elye

1

此鏈接幫助,但我不得不改變我的用例的幾件事情:http://artemzin.com/blog/use-okhttp-to-load-resources-for-webview/

下面的代碼工作:

webView = (WebView) findViewById(R.id.webView);  
WebSettings webSettings = webView.getSettings(); 

//enable javascript... 
webSettings.setJavaScriptEnabled(true); 

webView.setWebViewClient(new WebViewClient() { 
    @Override 
    public void onPageFinished(WebView view, String url) { 
     super.onPageFinished(view, url); 
     progress.dismiss(); 
    } 

    @SuppressWarnings("deprecation") 
    @Override 
    public WebResourceResponse shouldInterceptRequest(@NonNull WebView view, @NonNull String url) { 
     return handleRequestViaOkHttp(url); 
    } 
}); 

webView.loadUrl("MY_URL.COM"); 

然後,做了基本身份驗證+代碼處理攔截使用OkHTTPClient的webview請求。

@NonNull 
private WebResourceResponse handleRequestViaOkHttp(@NonNull String url) { 
    try { 
     OkHttpClient client = new OkHttpClient(); 

     client.setAuthenticator(new Authenticator() { 

      //for basic authorization... 
      @Override 
      public Request authenticate(Proxy proxy, com.squareup.okhttp.Response response) throws IOException { 
       String credential = Credentials.basic(CommonResource.HEADER_USERNAME, CommonResource.HEADER_PASSWORD); 
       return response.request().newBuilder().header("Authorization", credential).build(); 
      } 

      @Override 
      public Request authenticateProxy(Proxy proxy, com.squareup.okhttp.Response response) throws IOException { 
       return null; 
      } 
     }); 

     final Call call = client.newCall(new Request.Builder() 
      .url(url) 
      .build() 
     ); 

     final Response response = call.execute(); 

     return new WebResourceResponse("text/html", "UTF-8", response.body().byteStream()); 
    } catch (Exception e) { 
     e.printStackTrace(); 
     return null; 
    } 
} 
+0

這將是非常酷是有人想追加到代碼,以允許在現有的表格上發佈信息:) –

+1

這不是一個好主意,請參閱https://artemzin.com/blog/android-webview-io/。 攔截webview網絡請求會使它們在chrome 47之前順序執行,而5.0之前的Android客戶端不會更新其web視圖。 – RyanCheu

相關問題