From a5be2c59be414b78f27a347e81f236c8f6b592d5 Mon Sep 17 00:00:00 2001 From: Ben Anderson Date: Tue, 30 Aug 2022 12:16:43 +1200 Subject: [PATCH] Allow a cookie without a domain to be set on Android The other CookieManager implementations in Flutter allow for no domain, as the Android CookieManager implementation. By providing a default domain, applications cannot opt-out of the default CookieManager.setCookie behaviour (which prepends a "period" to the domain), which is treated as a different domain by Webkit on Android. This leads to multiple cookies for the same URL if the server serves a cookie without a domain, or with a domain that does not contain a leading period. Note, iOS's setCookie doesn't take a url parameter (at least in the way it's called from flutter_inappwebview) and instead this is passed an attribute on the HTTPCookie object itself (originURL). When constructing a HTTPCookie you must supply either originURL OR domain. Both a permitted, but at least one must be present. [1] By making domain optional, without a default, on both platforms, consumers can now set cookies that don't use the domain attribute but still allows for setting a domain when required. [1] https://developer.apple.com/documentation/foundation/httpcookie/1392975-init --- .../flutter_inappwebview/MyCookieManager.java | 5 ++++- ios/Classes/MyCookieManager.swift | 12 ++++++++---- lib/src/cookie_manager.dart | 10 ++++------ 3 files changed, 16 insertions(+), 11 deletions(-) diff --git a/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/MyCookieManager.java b/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/MyCookieManager.java index 5ed98435..a6ba6d9e 100755 --- a/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/MyCookieManager.java +++ b/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/MyCookieManager.java @@ -140,7 +140,10 @@ public class MyCookieManager implements MethodChannel.MethodCallHandler { cookieManager = getCookieManager(); if (cookieManager == null) return; - String cookieValue = name + "=" + value + "; Domain=" + domain + "; Path=" + path; + String cookieValue = name + "=" + value + "; Path=" + path; + + if (domain != null) + cookieValue += "; Domain=" + domain; if (expiresDate != null) cookieValue += "; Expires=" + getCookieExpirationDate(expiresDate); diff --git a/ios/Classes/MyCookieManager.swift b/ios/Classes/MyCookieManager.swift index 1f892d87..1e13d88f 100755 --- a/ios/Classes/MyCookieManager.swift +++ b/ios/Classes/MyCookieManager.swift @@ -35,7 +35,6 @@ class MyCookieManager: NSObject, FlutterPlugin { let url = arguments!["url"] as! String let name = arguments!["name"] as! String let value = arguments!["value"] as! String - let domain = arguments!["domain"] as! String let path = arguments!["path"] as! String var expiresDate: Int64? @@ -47,12 +46,13 @@ class MyCookieManager: NSObject, FlutterPlugin { let isSecure = arguments!["isSecure"] as? Bool let isHttpOnly = arguments!["isHttpOnly"] as? Bool let sameSite = arguments!["sameSite"] as? String + let domain = arguments!["domain"] as? String MyCookieManager.setCookie(url: url, name: name, value: value, - domain: domain, path: path, + domain: domain, expiresDate: expiresDate, maxAge: maxAge, isSecure: isSecure, @@ -92,8 +92,8 @@ class MyCookieManager: NSObject, FlutterPlugin { public static func setCookie(url: String, name: String, value: String, - domain: String, path: String, + domain: String?, expiresDate: Int64?, maxAge: Int64?, isSecure: Bool?, @@ -109,8 +109,12 @@ class MyCookieManager: NSObject, FlutterPlugin { properties[.originURL] = url properties[.name] = name properties[.value] = value - properties[.domain] = domain properties[.path] = path + + if domain != nil { + properties[.domain] = domain + } + if expiresDate != nil { // convert from milliseconds properties[.expires] = Date(timeIntervalSince1970: TimeInterval(Double(expiresDate!)/1000)) diff --git a/lib/src/cookie_manager.dart b/lib/src/cookie_manager.dart index 7839a501..fbfdaac0 100755 --- a/lib/src/cookie_manager.dart +++ b/lib/src/cookie_manager.dart @@ -63,12 +63,9 @@ class CookieManager { bool? isHttpOnly, HTTPCookieSameSitePolicy? sameSite, InAppWebViewController? iosBelow11WebViewController}) async { - if (domain == null) domain = _getDomainName(url); - assert(url.toString().isNotEmpty); assert(name.isNotEmpty); assert(value.isNotEmpty); - assert(domain.isNotEmpty); assert(path.isNotEmpty); if (defaultTargetPlatform == TargetPlatform.iOS) { @@ -109,15 +106,16 @@ class CookieManager { {required Uri url, required String name, required String value, - required String domain, String path = "/", + String? domain, int? expiresDate, int? maxAge, bool? isSecure, HTTPCookieSameSitePolicy? sameSite, InAppWebViewController? webViewController}) async { - var cookieValue = - name + "=" + value + "; Domain=" + domain + "; Path=" + path; + var cookieValue = name + "=" + value + "; Path=" + path; + + if (domain != null) cookieValue += "; Domain=" + domain; if (expiresDate != null) cookieValue += "; Expires=" + await _getCookieExpirationDate(expiresDate);