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
This commit is contained in:
Ben Anderson 2022-08-30 12:16:43 +12:00
parent ee1b0d7ff7
commit a5be2c59be
3 changed files with 16 additions and 11 deletions

View File

@ -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);

View File

@ -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))

View File

@ -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);