diff --git a/plugins/WebViewObject.cs b/plugins/WebViewObject.cs index ff0dbbc3..7077b21e 100644 --- a/plugins/WebViewObject.cs +++ b/plugins/WebViewObject.cs @@ -346,6 +346,10 @@ private static extern void _CWebViewPlugin_GoForward( private static extern string _CWebViewPlugin_GetCookies(string url); [DllImport("__Internal")] private static extern void _CWebViewPlugin_SetBasicAuthInfo(IntPtr instance, string userName, string password); + [DllImport("__Internal")] + private static extern string _CWebViewPlugin_GetSessionCookieFromServer(IntPtr instance); + [DllImport("__Internal")] + private static extern void _CWebViewPlugin_SetSessionCookieFromClient(IntPtr instance, string cookie); #elif UNITY_WEBGL [DllImport("__Internal")] private static extern void _gree_unity_webview_init(string name); @@ -999,6 +1003,43 @@ public void SetBasicAuthInfo(string userName, string password) #endif } + public string GetSessionCookieFromServer() + { +#if UNITY_WEBPLAYER || UNITY_WEBGL + //TODO: UNSUPPORTED + return ""; +#elif UNITY_EDITOR_WIN || UNITY_STANDALONE_WIN || UNITY_EDITOR_LINUX + //TODO: UNSUPPORTED + return ""; +#elif UNITY_EDITOR_OSX || UNITY_STANDALONE_OSX + //TODO: UNSUPPORTED + return ""; +#elif UNITY_IPHONE + if (webView == IntPtr.Zero) + return ""; + return _CWebViewPlugin_GetSessionCookieFromServer(webView); +#elif UNITY_ANDROID + //TODO: UNSUPPORTED + return ""; +#endif + } + + public void SetSessionCookieFromClient(string cookie) + { +#if UNITY_WEBPLAYER || UNITY_WEBGL + //TODO: UNSUPPORTED +#elif UNITY_EDITOR_WIN || UNITY_STANDALONE_WIN || UNITY_EDITOR_LINUX + //TODO: UNSUPPORTED +#elif UNITY_EDITOR_OSX || UNITY_STANDALONE_OSX + //TODO: UNSUPPORTED +#elif UNITY_IPHONE + if (webView == IntPtr.Zero) + return; + _CWebViewPlugin_SetSessionCookieFromClient(webView, cookie); +#elif UNITY_ANDROID + //TODO: UNSUPPORTED +#endif + } #if UNITY_EDITOR_OSX || UNITY_STANDALONE_OSX void OnApplicationFocus(bool focus) diff --git a/plugins/iOS/WebView.mm b/plugins/iOS/WebView.mm index e01751dc..577ddb16 100644 --- a/plugins/iOS/WebView.mm +++ b/plugins/iOS/WebView.mm @@ -88,6 +88,8 @@ - (void)setScrollBounce:(BOOL)enable @end +// cf. https://stackoverflow.com/questions/26573137/can-i-set-the-cookies-to-be-used-by-a-wkwebview/26577303#26577303 + @interface CWebViewPlugin : NSObject { UIView *webView; @@ -99,6 +101,8 @@ @interface CWebViewPlugin : NSObject * cookies) { + for (NSHTTPCookie *cookie in cookies) { + if (cookie.sessionOnly) { + sessionCookieFromServer = cookie; + } + } + UnitySendMessage( + [gameObjectName UTF8String], + "CallOnLoaded", + [[[webView URL] absoluteString] UTF8String]); + }]; } } @@ -695,6 +708,80 @@ - (void)setBasicAuthInfo:(const char *)userName password:(const char *)password basicAuthUserName = [NSString stringWithUTF8String:userName]; basicAuthPassword = [NSString stringWithUTF8String:password]; } + +- (const char *)getSessionCookieFromServer +{ + if (sessionCookieFromServer == nil) { + return NULL; + } + NSDateFormatter *formatter = [[NSDateFormatter alloc] init]; + formatter.locale = [NSLocale localeWithLocaleIdentifier:@"en_US_POSIX"]; + [formatter setDateFormat:@"EEE, dd MMM yyyy HH:mm:ss zzz"]; + NSHTTPCookie *cookie = sessionCookieFromServer; + NSMutableString *result = [NSMutableString string]; + [result appendString:[NSString stringWithFormat:@"%@=%@", cookie.name, cookie.value]]; + if ([cookie.domain length] > 0) { + [result appendString:[NSString stringWithFormat:@"; "]]; + [result appendString:[NSString stringWithFormat:@"Domain=%@", cookie.domain]]; + } + if ([cookie.path length] > 0) { + [result appendString:[NSString stringWithFormat:@"; "]]; + [result appendString:[NSString stringWithFormat:@"Path=%@", cookie.path]]; + } + if (cookie.expiresDate != nil) { + [result appendString:[NSString stringWithFormat:@"; "]]; + [result appendString:[NSString stringWithFormat:@"Expires=%@", [formatter stringFromDate:cookie.expiresDate]]]; + } + [result appendString:[NSString stringWithFormat:@"; "]]; + [result appendString:[NSString stringWithFormat:@"Version=%zd", cookie.version]]; + const char *s = [result UTF8String]; + char *r = (char *)malloc(strlen(s) + 1); + strcpy(r, s); + return r; +} + +- (void)setSessionCookieFromClient:(const char *)cookie +{ + sessionCookieFromClient = nil; + if (cookie == nil || strlen(cookie) == 0) { + return; + } + NSError *err = nil; + NSRegularExpression *re = [NSRegularExpression regularExpressionWithPattern:@"([^=; ]+)=([^=;]+)" options:0 error:&err]; + if (err != nil) { + return; + } + NSMutableDictionary *props = [[NSMutableDictionary alloc] init]; + NSString *str = [NSString stringWithUTF8String:cookie]; + NSArray *matches = [re matchesInString:str options:0 range:NSMakeRange(0, strlen(cookie))]; + [matches enumerateObjectsUsingBlock:^(NSTextCheckingResult *result, NSUInteger idx, BOOL *stop) { + NSString *k = [str substringWithRange:[result rangeAtIndex:1]]; + NSString *v = [str substringWithRange:[result rangeAtIndex:2]]; + if (idx == 0) { + [props setValue:k forKey:NSHTTPCookieName]; + [props setValue:v forKey:NSHTTPCookieValue]; + } else if ([k isEqualToString:@"Domain"]) { + [props setValue:v forKey:NSHTTPCookieDomain]; + } else if ([k isEqualToString:@"Path"]) { + [props setValue:v forKey:NSHTTPCookiePath]; + } else if ([k isEqualToString:@"Version"]) { + [props setValue:v forKey:NSHTTPCookieVersion]; + } else if ([k isEqualToString:@"Expires"]) { + NSDateFormatter *formatter = [[NSDateFormatter alloc] init]; + formatter.locale = [NSLocale localeWithLocaleIdentifier:@"en_US_POSIX"]; + [formatter setDateFormat:@"EEE, dd MMM yyyy HH:mm:ss zzz"]; + NSDate *d = [formatter dateFromString:v]; + [props setValue:d forKey:k]; + } + }]; + if (props.count == 0) { + return; + } + sessionCookieFromClient = [[NSHTTPCookie alloc] initWithProperties: props]; + WKWebView *wkWebView = (WKWebView *)webView; + WKHTTPCookieStore *cookieStore = wkWebView.configuration.websiteDataStore.httpCookieStore; + [cookieStore setCookie:sessionCookieFromClient completionHandler:^{}]; +} @end extern "C" { @@ -722,6 +809,8 @@ void _CWebViewPlugin_SetMargins( const char *_CWebViewPlugin_GetCookies(const char *url); const char *_CWebViewPlugin_GetCustomHeaderValue(void *instance, const char *headerKey); void _CWebViewPlugin_SetBasicAuthInfo(void *instance, const char *userName, const char *password); + const char *_CWebViewPlugin_GetSessionCookieFromServer(void *instance); + void _CWebViewPlugin_SetSessionCookieFromClient(void *instance, const char *cookie); } void *_CWebViewPlugin_Init(const char *gameObjectName, BOOL transparent, const char *ua, BOOL enableWKWebView) @@ -903,4 +992,20 @@ void _CWebViewPlugin_SetBasicAuthInfo(void *instance, const char *userName, cons [webViewPlugin setBasicAuthInfo:userName password:password]; } +const char *_CWebViewPlugin_GetSessionCookieFromServer(void *instance) +{ + if (instance == NULL) + return NULL; + CWebViewPlugin *webViewPlugin = (__bridge CWebViewPlugin *)instance; + return [webViewPlugin getSessionCookieFromServer]; +} + +void _CWebViewPlugin_SetSessionCookieFromClient(void *instance, const char *cookie) +{ + if (instance == NULL) + return; + CWebViewPlugin *webViewPlugin = (__bridge CWebViewPlugin *)instance; + [webViewPlugin setSessionCookieFromClient:cookie]; +} + #endif // !(__IPHONE_OS_VERSION_MIN_REQUIRED < __IPHONE_9_0) diff --git a/sample/Assets/Scripts/SampleWebView.cs b/sample/Assets/Scripts/SampleWebView.cs index c6d01bcc..d20104f9 100644 --- a/sample/Assets/Scripts/SampleWebView.cs +++ b/sample/Assets/Scripts/SampleWebView.cs @@ -57,6 +57,9 @@ IEnumerator Start() }, ld: (msg) => { +#if UNITY_IPHONE + PlayerPrefs.SetString("sessionCookie", webViewObject.GetSessionCookieFromServer()); +#endif Debug.Log(string.Format("CallOnLoaded[{0}]", msg)); #if UNITY_EDITOR_OSX || !UNITY_ANDROID // NOTE: depending on the situation, you might prefer @@ -104,6 +107,12 @@ IEnumerator Start() }, //ua: "custom user agent string", enableWKWebView: true); +#if UNITY_IPHONE + if (!string.IsNullOrEmpty(PlayerPrefs.GetString("sessionCookie", ""))) { + webViewObject.SetSessionCookieFromClient(PlayerPrefs.GetString("sessionCookie", "")); + } +#endif + #if UNITY_EDITOR_OSX || UNITY_STANDALONE_OSX webViewObject.bitmapRefreshCycle = 1; #endif