From dda4ac0ce795960597274485b235f85355966c79 Mon Sep 17 00:00:00 2001 From: Akmal Rakhimov Date: Mon, 22 Jun 2020 17:36:25 -0400 Subject: [PATCH 1/2] Implemented getAllCookies method that returns all the cookies including httponly ones. Current getCookies() method doesn't return httponly cookies such as SESSION. --- .../FlutterWebviewPlugin.java | 9 +++++++ .../WebviewManager.java | 7 ++++++ ios/Classes/FlutterWebviewPlugin.m | 24 +++++++++++++++++++ lib/src/base.dart | 16 +++++++++++++ 4 files changed, 56 insertions(+) diff --git a/android/src/main/java/com/flutter_webview_plugin/FlutterWebviewPlugin.java b/android/src/main/java/com/flutter_webview_plugin/FlutterWebviewPlugin.java index 71e90444..0aeb8d02 100644 --- a/android/src/main/java/com/flutter_webview_plugin/FlutterWebviewPlugin.java +++ b/android/src/main/java/com/flutter_webview_plugin/FlutterWebviewPlugin.java @@ -94,12 +94,21 @@ public void onMethodCall(MethodCall call, MethodChannel.Result result) { case "cleanCache": cleanCache(result); break; + case "getAllCookies": + getAllCookies(call, result); + break; default: result.notImplemented(); break; } } + private void getAllCookies(MethodCall call, final MethodChannel.Result result){ + if (webViewManager != null){ + webViewManager.getAllCookies(call,result); + } + } + private void cleanCache(MethodChannel.Result result) { webViewManager.cleanCache(); WebStorage.getInstance().deleteAllData(); diff --git a/android/src/main/java/com/flutter_webview_plugin/WebviewManager.java b/android/src/main/java/com/flutter_webview_plugin/WebviewManager.java index e19b2a08..262b7650 100644 --- a/android/src/main/java/com/flutter_webview_plugin/WebviewManager.java +++ b/android/src/main/java/com/flutter_webview_plugin/WebviewManager.java @@ -347,6 +347,13 @@ public void onReceiveValue(Boolean aBoolean) { } } + void getAllCookies(MethodCall call, final MethodChannel.Result result){ + String url = call.argument("url"); + CookieManager cookieManager = CookieManager.getInstance(); + String cookieStr = cookieManager.getCookie(url); + result.success(cookieStr); + } + private void clearCache() { webView.clearCache(true); webView.clearFormData(); diff --git a/ios/Classes/FlutterWebviewPlugin.m b/ios/Classes/FlutterWebviewPlugin.m index fc266094..3b64e3ba 100644 --- a/ios/Classes/FlutterWebviewPlugin.m +++ b/ios/Classes/FlutterWebviewPlugin.m @@ -79,6 +79,10 @@ - (void)handleMethodCall:(FlutterMethodCall*)call result:(FlutterResult)result { [self onCanGoForward:call result:result]; } else if ([@"cleanCache" isEqualToString:call.method]) { [self cleanCache:result]; + } else if ([@"getAllCookies" isEqualToString:call.method]) { + [self getAllCookies:call completionHandler:^(NSString *cookies) { + result(cookies); + }]; } else { result(FlutterMethodNotImplemented); } @@ -303,6 +307,26 @@ - (void)cleanCookies:(FlutterResult)result { } } +- (void)getAllCookies:(FlutterMethodCall*)call + completionHandler:(void (^_Nullable)(NSString * cookies))completionHandler { + if (self.webview != nil) { + NSString *url = call.arguments[@"url"]; + WKHTTPCookieStore *cookieStore = self.webview.configuration.websiteDataStore.httpCookieStore; + [cookieStore getAllCookies:^(NSArray * _Nonnull cookies) { + NSString *allCookies = @""; + NSEnumerator *cookie_enum = [cookies objectEnumerator]; + NSHTTPCookie *temp_cookie; + while (temp_cookie = [cookie_enum nextObject]) { + NSString *temp = [NSString stringWithFormat:@"%@=%@;",[temp_cookie name],[temp_cookie value]]; + allCookies = [allCookies stringByAppendingString:temp]; + } + completionHandler([NSString stringWithFormat:@"%@", allCookies]); + }]; + } else { + completionHandler(nil); + } +} + - (void)cleanCache:(FlutterResult)result { if (self.webview != nil) { if (@available(iOS 9.0, *)) { diff --git a/lib/src/base.dart b/lib/src/base.dart index 05de5db8..d608c6f2 100644 --- a/lib/src/base.dart +++ b/lib/src/base.dart @@ -295,6 +295,22 @@ class FlutterWebviewPlugin { _instance = null; } + // get all cookies including HttpOnly + // but for ios, it only support ios 11 or above + Future> getAllCookies(String url) async { + final cookiesString = await _channel.invokeMethod('getAllCookies', {'url': url}); + final cookies = {}; + + if (cookiesString?.isNotEmpty == true) { + cookiesString.split(';').forEach((String cookie) { + final split = cookie.split('='); + cookies[split[0].trim()] = split[1].trim(); + }); + } + + return cookies; + } + Future> getCookies() async { final cookiesString = await evalJavascript('document.cookie'); final cookies = {}; From 76f6cac2bff76c3c356c3aaf5f4cc8bc6339412d Mon Sep 17 00:00:00 2001 From: Akmal Rakhimov Date: Tue, 23 Jun 2020 07:44:51 -0400 Subject: [PATCH 2/2] Fixed a bug when it tries to split empty string by = character and fails. --- lib/src/base.dart | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/lib/src/base.dart b/lib/src/base.dart index d608c6f2..a88f9a7a 100644 --- a/lib/src/base.dart +++ b/lib/src/base.dart @@ -303,8 +303,10 @@ class FlutterWebviewPlugin { if (cookiesString?.isNotEmpty == true) { cookiesString.split(';').forEach((String cookie) { - final split = cookie.split('='); - cookies[split[0].trim()] = split[1].trim(); + if (cookie.isNotEmpty && cookie.contains('=')) { + final split = cookie.split('='); + cookies[split[0].trim()] = split[1].trim(); + } }); }