iOS and H5 page interaction (WKWebview and UIWebview cookie settings)

Mainly record the cookie related pits

1. UIWebview

1. UIWebview is relatively simple and can be realized directly by setting cookies through NSHTTPCookieStorage.

Code part

```
  NSURL *cookieHost = [NSURL URLWithString:self.domain];
// Set cookie s
NSHTTPCookie *cookie = [NSHTTPCookie cookieWithProperties:
                        [NSDictionary dictionaryWithObjectsAndKeys:
                         [cookieHost host], NSHTTPCookieDomain,
                         [cookieHost path], NSHTTPCookiePath,
                         self.cookieKey,  NSHTTPCookieName,
                         self.cookieValue, NSHTTPCookieValue,
                         nil]];
// Join cookie
[[NSHTTPCookieStorage sharedHTTPCookieStorage] setCookie:cookie];
```

2. If you need to set HeaderValue in HTTPRequest through setValueForKey at the first request

2. WKWebview

When using WKWebview, it also needs to be passed in two situations:

  • 1. When httprequest requests the URL, it carries a cookie, such as the backend PHP.
  • 2. The purpose of injecting js is to let the front end get cookies from the inside of the page, which can be passed through js when the document.cookie setting is initialized through WKWebview.

    `WKUserScript * cookieScript = [[WKUserScript alloc] initWithSource: cookieValue injectionTime:WKUserScriptInjectionTimeAtDocumentStart forMainFrameOnly:NO];

  • 3. It seems that nshttpcookiestorage does not have any problem, because we do not pass cookies through it at present.

The method of online reference to others is to realize the following steps, but our project does not follow these three necessary ways, but we can make a reference:

There are three processing steps of WKWebview: (1) iOS11, WKHTTPCookieStore direct delivery. (if only IOS 11 is supported, the next two steps can be omitted); (2) IOS 8-ios 10, js injection; (3) PHP carries cookies

Related code

#pragma mark - WKWebview
// iOS11
- (void)setWkCookie:(WKWebView *)wkWebview completionHandler:(nullable void (^)(void))comple {
    
    NSURL *cookieHost = [NSURL URLWithString:self.domain];
    // Set cookie s
    NSHTTPCookie *cookie = [NSHTTPCookie cookieWithProperties:
                            [NSDictionary dictionaryWithObjectsAndKeys:
                             [cookieHost host], NSHTTPCookieDomain,
                             [cookieHost path], NSHTTPCookiePath,
                             self.cookieKey,  NSHTTPCookieName,
                             self.cookieValue, NSHTTPCookieValue,
                             //                             [NSDate dateWithTimeIntervalSinceNow:30*60*60],NSHTTPCookieExpires,
                             nil]];
    
    // Join cookie
    //Insert a cookie before sending the request;
    if (@available(iOS 11.0, *)) {
        WKHTTPCookieStore *cookieStore = wkWebview.configuration.websiteDataStore.httpCookieStore;
        [cookieStore setCookie:cookie completionHandler:^{
            
            comple?comple():nil;
        }];
    } else {
        
        
    }

}

// The way JS carries cookie s
- (void)setWkJsCookie:(WKUserContentController *)userContentController {
    // Single cookie, if more than one, plus document.cookie = '% @ =% @'; once
    NSString *cookieStr = [NSString stringWithFormat:@"document.cookie ='%@=%@';",self.cookieKey,self.cookieValue];
    WKUserScript * cookieScript = [[WKUserScript alloc] initWithSource: cookieStr injectionTime:WKUserScriptInjectionTimeAtDocumentStart forMainFrameOnly:NO];
    [userContentController addUserScript:cookieScript];
}

// The way PHP carries cookie s
- (void)setWkPHPCookie:(NSMutableURLRequest *)request {
    //Associate cookie s through host.
    NSMutableDictionary *cookieDic = [NSMutableDictionary dictionary];
    NSMutableString *cookieValue = [NSMutableString stringWithFormat:@""];
    NSHTTPCookieStorage *cookieStorage = [NSHTTPCookieStorage sharedHTTPCookieStorage];
    for (NSHTTPCookie *cookie in [cookieStorage cookies]) {
        [cookieDic setObject:cookie.value forKey:cookie.name];
    }
    if ([cookieDic objectForKey:[CookieManager shareInstance].cookieKey]) {
        [cookieDic removeObjectForKey:[CookieManager shareInstance].cookieKey];
    }
    
    // Repeat the cookie, put it in the dictionary for de duplication, and then splice it.
    for (NSString *key in cookieDic) {
        NSString *appendString = [NSString stringWithFormat:@"%@=%@;", key, [cookieDic valueForKey:key]];
        [cookieValue appendString:appendString];
    }
    
    [cookieValue appendString:[NSString stringWithFormat:@"%@ = %@;",self.cookieKey,self.cookieValue]];
    [request addValue:cookieValue forHTTPHeaderField:@"Cookie"];
}
#pragma mark - Webview
// Client add cookie
- (void)setWebCookie {
    
    NSURL *cookieHost = [NSURL URLWithString:self.domain];
    // Set cookie s
    NSHTTPCookie *cookie = [NSHTTPCookie cookieWithProperties:
                            [NSDictionary dictionaryWithObjectsAndKeys:
                             [cookieHost host], NSHTTPCookieDomain,
                             [cookieHost path], NSHTTPCookiePath,
                             self.cookieKey,  NSHTTPCookieName,
                             self.cookieValue, NSHTTPCookieValue,
                             nil]];
    // Join cookie
    [[NSHTTPCookieStorage sharedHTTPCookieStorage] setCookie:cookie];
}

2.WKWebview has cross domain problems

*Finally, if the above methods are considered cross domain, UIWebView will not appear, but WKWebview is not allowed to cross domain. This is also Apple's consideration of security, but it can be handled. At present, our solutions are as follows

1. The front end replays the cookie s after obtaining them, and blurs them through. xxx.com.

2. Let the back-end handle it, and you can pass user related information such as uid to the front-end.

Keywords: iOS PHP

Added by DasHaas on Wed, 23 Oct 2019 22:15:01 +0300