Okhttpclient Pass Cookies To Webview
I am logging in as a user via an OKHttpClient post and I would like to share the cookies with the webview.
Solution 1:
With OkHttp 3.0, you can use a method similar to sharing with HttpURLConnection by making a WebkitCookieManagerProxy that uses the webkit cookie store. Adapted from Pass cookies from HttpURLConnection (java.net.CookieManager) to WebView (android.webkit.CookieManager) .
publicclassWebkitCookieManagerProxyextendsCookieManagerimplementsCookieJar {
private android.webkit.CookieManager webkitCookieManager;
privatestatic final StringTAG = WebkitCookieManagerProxy.class.getSimpleName();
publicWebkitCookieManagerProxy() {
this(null, null);
}
WebkitCookieManagerProxy(CookieStore store, CookiePolicy cookiePolicy) {
super(null, cookiePolicy);
this.webkitCookieManager = android.webkit.CookieManager.getInstance();
}
@Overridepublicvoidput(URI uri, Map<String, List<String>> responseHeaders)
throws IOException {
// make sure our args are validif ((uri == null) || (responseHeaders == null))
return;
// save our url onceString url = uri.toString();
// go over the headersfor (String headerKey : responseHeaders.keySet()) {
// ignore headers which aren't cookie relatedif ((headerKey == null)
|| !(headerKey.equalsIgnoreCase("Set-Cookie2") || headerKey
.equalsIgnoreCase("Set-Cookie")))
continue;
// process each of the headersfor (String headerValue : responseHeaders.get(headerKey)) {
webkitCookieManager.setCookie(url, headerValue);
}
}
}
@OverridepublicMap<String, List<String>> get(URI uri,
Map<String, List<String>> requestHeaders) throws IOException {
// make sure our args are validif ((uri == null) || (requestHeaders == null))
thrownewIllegalArgumentException("Argument is null");
// save our url onceString url = uri.toString();
// prepare our responseMap<String, List<String>> res = new java.util.HashMap<String, List<String>>();
// get the cookieString cookie = webkitCookieManager.getCookie(url);
// return itif (cookie != null) {
res.put("Cookie", Arrays.asList(cookie));
}
return res;
}
@OverridepublicCookieStoregetCookieStore() {
// we don't want anyone to work with this cookie store directlythrownewUnsupportedOperationException();
}
@OverridepublicvoidsaveFromResponse(HttpUrl url, List<Cookie> cookies) {
HashMap<String, List<String>> generatedResponseHeaders = newHashMap<>();
ArrayList<String> cookiesList = newArrayList<>();
for(Cookiec: 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);
}
}
@OverridepublicList<Cookie> loadForRequest(HttpUrl url) {
ArrayList<Cookie> cookieArrayList = newArrayList<>();
try {
Map<String, List<String>> cookieList = get(url.uri(), newHashMap<String, List<String>>());
// Format here looks like: "Cookie":["cookie1=val1;cookie2=val2;"]for (List<String> ls : cookieList.values()) {
for (Strings: 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;
}
}
Then add an instance of the proxy as your cookieJar when building the OkHttpClient.
client = new OkHttpClient.Builder().cookieJar(proxy).build();Solution 2:
This link helped but I had to modify a few things for my use-case: http://artemzin.com/blog/use-okhttp-to-load-resources-for-webview/
The below code works:
webView = (WebView) findViewById(R.id.webView);
WebSettings webSettings = webView.getSettings();
//enable javascript...
webSettings.setJavaScriptEnabled(true);
webView.setWebViewClient(newWebViewClient() {
@OverridepublicvoidonPageFinished(WebView view, String url) {
super.onPageFinished(view, url);
progress.dismiss();
}
@SuppressWarnings("deprecation")
@OverridepublicWebResourceResponseshouldInterceptRequest(@NonNull WebView view, @NonNullString url) {
returnhandleRequestViaOkHttp(url);
}
});
webView.loadUrl("MY_URL.COM");
Then the code that does the basic auth + handles intercepting the webview request using OkHTTPClient.
@NonNullprivate WebResourceResponse handleRequestViaOkHttp(@NonNull String url) {
try {
OkHttpClientclient=newOkHttpClient();
client.setAuthenticator(newAuthenticator() {
//for basic authorization...@Overridepublic Request authenticate(Proxy proxy, com.squareup.okhttp.Response response)throws IOException {
Stringcredential= Credentials.basic(CommonResource.HEADER_USERNAME, CommonResource.HEADER_PASSWORD);
return response.request().newBuilder().header("Authorization", credential).build();
}
@Overridepublic Request authenticateProxy(Proxy proxy, com.squareup.okhttp.Response response)throws IOException {
returnnull;
}
});
finalCallcall= client.newCall(newRequest.Builder()
.url(url)
.build()
);
finalResponseresponse= call.execute();
returnnewWebResourceResponse("text/html", "UTF-8", response.body().byteStream());
} catch (Exception e) {
e.printStackTrace();
returnnull;
}
}
Solution 3:
If all you care about is OkHttp + WebView than it can be as simple as this:
classWebkitCookieManager(privateval cookieManager: CookieManager) : CookieJar {
overridefunsaveFromResponse(url: HttpUrl, cookies: List<Cookie>) {
cookies.forEach { cookie ->
cookieManager.setCookie(url.toString(), cookie.toString())
}
}
overridefunloadForRequest(url: HttpUrl): List<Cookie> =
when (val cookies = cookieManager.getCookie(url.toString())) {
null -> emptyList()
else -> cookies.split("; ").mapNotNull { Cookie.parse(url, it) }
}
}
....
Usage:
1. OkHttp
OkHttpClient.Builder().cookieJar(webkitCookieManager)
2. WebView
CookieManager.getInstance().setCookie()
No need to support HttpURLConnection if it's not being used.
Post a Comment for "Okhttpclient Pass Cookies To Webview"