美文网首页iOS开发技巧
WKWebview注入Cookie和删除Cookie

WKWebview注入Cookie和删除Cookie

作者: wuyukobe | 来源:发表于2020-08-27 20:35 被阅读0次

    最近研究了一下给webview注入Cookie,主要针对的是WKWebview,毕竟UIWebview到年底苹果就不再支持了。而且针对WKWebview,苹果在iOS11之后新出了类WKHTTPCookieStore 以及对应的API来操作Cookie。

    一、Cookie的生成

    首先看下生成Cookie的类 NSHTTPCookie,打开源码可以看到要生成Cookie所对应的key值,里面包括:name、value、url、版本、域名、过期日期等等key值,如下:

    FOUNDATION_EXPORT NSHTTPCookiePropertyKey const NSHTTPCookieName;
    FOUNDATION_EXPORT NSHTTPCookiePropertyKey const NSHTTPCookieValue;
    FOUNDATION_EXPORT NSHTTPCookiePropertyKey const NSHTTPCookieOriginURL;
    FOUNDATION_EXPORT NSHTTPCookiePropertyKey const NSHTTPCookieVersion;
    FOUNDATION_EXPORT NSHTTPCookiePropertyKey const NSHTTPCookieDomain;
    FOUNDATION_EXPORT NSHTTPCookiePropertyKey const NSHTTPCookiePath;
    FOUNDATION_EXPORT NSHTTPCookiePropertyKey const NSHTTPCookieSecure;
    FOUNDATION_EXPORT NSHTTPCookiePropertyKey const NSHTTPCookieExpires;
    FOUNDATION_EXPORT NSHTTPCookiePropertyKey const NSHTTPCookieComment;
    FOUNDATION_EXPORT NSHTTPCookiePropertyKey const NSHTTPCookieCommentURL;
    FOUNDATION_EXPORT NSHTTPCookiePropertyKey const NSHTTPCookieDiscard;
    FOUNDATION_EXPORT NSHTTPCookiePropertyKey const NSHTTPCookieMaximumAge;
    FOUNDATION_EXPORT NSHTTPCookiePropertyKey const NSHTTPCookiePort;
    FOUNDATION_EXPORT NSHTTPCookiePropertyKey const NSHTTPCookieSameSitePolicy API_AVAILABLE(macos(10.15), ios(13.0), watchos(6.0), tvos(13.0));
    FOUNDATION_EXPORT NSHTTPCookieStringPolicy const NSHTTPCookieSameSiteLax API_AVAILABLE(macos(10.15), ios(13.0), watchos(6.0), tvos(13.0));
    FOUNDATION_EXPORT NSHTTPCookieStringPolicy const NSHTTPCookieSameSiteStrict API_AVAILABLE(macos(10.15), ios(13.0), watchos(6.0), tvos(13.0));
    

    还有可以直接获取Cookie的一些属性,不过都是只读的,如下:

    @property (nullable, readonly, copy) NSDictionary<NSHTTPCookiePropertyKey, id> *properties;
    @property (readonly) NSUInteger version;
    @property (readonly, copy) NSString *name;
    @property (readonly, copy) NSString *value;
    @property (nullable, readonly, copy) NSDate *expiresDate;
    @property (readonly, getter=isSessionOnly) BOOL sessionOnly;
    @property (readonly, copy) NSString *domain;
    @property (readonly, copy) NSString *path;
    @property (readonly, getter=isSecure) BOOL secure;
    @property (readonly, getter=isHTTPOnly) BOOL HTTPOnly;
    @property (nullable, readonly, copy) NSString *comment;
    @property (nullable, readonly, copy) NSURL *commentURL;
    @property (nullable, readonly, copy) NSArray<NSNumber *> *portList;
    @property (nullable, readonly, copy) NSHTTPCookieStringPolicy sameSitePolicy API_AVAILABLE(macos(10.15), ios(13.0), watchos(6.0), tvos(13.0));
    

    下面是生成Cookie的一些方法:

    - (nullable instancetype)initWithProperties:(NSDictionary<NSHTTPCookiePropertyKey, id> *)properties;
    + (nullable NSHTTPCookie *)cookieWithProperties:(NSDictionary<NSHTTPCookiePropertyKey, id> *)properties;
    

    其中 properties 就是一个字典,用来设置生成Cookie的一些键值对。
    所以可以用以下方式来生成Cookie:

    NSMutableDictionary *cookieProperties = [NSMutableDictionary dictionary];
    [cookieProperties setObject:@"name" forKey:NSHTTPCookieName];
    [cookieProperties setObject:@"value" forKey:NSHTTPCookieValue];
    [cookieProperties setObject:@"jianshu.com" forKey:NSHTTPCookieDomain];
    [cookieProperties setObject:@"jianshu.com" forKey:NSHTTPCookieOriginURL];
    [cookieProperties setObject:@"/" forKey:NSHTTPCookiePath];
    [cookieProperties setObject:@"0" forKey:NSHTTPCookieVersion];
    /// 设置失效时间,不要设置NSHTTPCookieDiscard(设置sessionOnly,会话操作使用)
    [cookieProperties setObject:[NSDate date] forKey:NSHTTPCookieExpires];
    NSHTTPCookie *cookie = [NSHTTPCookie cookieWithProperties:cookieProperties];
    

    其中有个需要注意的点,设置失效时间时,不要设置NSHTTPCookieDiscard。同时设置的话,失效时间会为nil,因为NSHTTPCookieDiscard 仅在会话操作时使用。

    二、Cookie的注入

    对于iOS11之前的系统,可以直接使用 NSHTTPCookieStorage 来注入 Cookie,如下:

    NSMutableDictionary *cookieProperties = [NSMutableDictionary dictionary];
    [cookieProperties setObject:@"name" forKey:NSHTTPCookieName];
    [cookieProperties setObject:@"value" forKey:NSHTTPCookieValue];
    [cookieProperties setObject:@"jianshu.com" forKey:NSHTTPCookieDomain];
    [cookieProperties setObject:@"jianshu.com" forKey:NSHTTPCookieOriginURL];
    [cookieProperties setObject:@"/" forKey:NSHTTPCookiePath];
    [cookieProperties setObject:@"0" forKey:NSHTTPCookieVersion];
    /// 设置失效时间,不要设置NSHTTPCookieDiscard(设置sessionOnly,会话操作使用)
        [cookieProperties setObject:[NSDate date] forKey:NSHTTPCookieExpires];
        NSHTTPCookie *cookie = [NSHTTPCookie cookieWithProperties:cookieProperties];
        [[NSHTTPCookieStorage sharedHTTPCookieStorage] setCookie:cookie];
    

    对于iOS11及之后的系统,需要将 NSHTTPCookieStorage中的Cookie信息复制到 WKHTTPCookieStore 中,以此来达到 WKWebView中注入Cookie 的目的。

    这是利用iOS11 API WKHTTPCookieStore 可以解决WKWebView首次请求不携带Cookie 的问题。因为WKWebView每次请求都会携带WKHTTPCookieStore里的Cookie。

    只需要在上述代码之后加入以下代码即可:

    if (@available(iOS 11, *)) {
        NSArray *cookies = [[NSHTTPCookieStorage sharedHTTPCookieStorage] cookies];
        WKHTTPCookieStore *cookieStore = webview.configuration.websiteDataStore.httpCookieStore;
        for (NSHTTPCookie *cookie in cookies) {
            [cookieStore setCookie:cookie completionHandler:nil];
        }
        [cookieStore setCookie:cookie completionHandler:nil];
    }
    
    三、Cookie的删除

    iOS11之前的系统可以使用下面的方法来删除Cookie:

    [[WKWebsiteDataStore defaultDataStore] fetchDataRecordsOfTypes:[NSSet setWithObjects:WKWebsiteDataTypeCookies, nil] completionHandler:^(NSArray<WKWebsiteDataRecord *> * _Nonnull records) {
         [[WKWebsiteDataStore defaultDataStore] removeDataOfTypes:[WKWebsiteDataStore allWebsiteDataTypes] forDataRecords:records completionHandler:^{
    
        }];
    }];
    

    NSArray * cookArray = [[NSHTTPCookieStorage sharedHTTPCookieStorage] cookies];
    for (NSHTTPCookie *cookie in cookArray) {
        if ([cookie.domain isEqualToString:@"jianshu.com"]) {
            [[NSHTTPCookieStorage sharedHTTPCookieStorage] deleteCookie:cookie];
        }
    }
    

    iOS11及之后的系统可以使用WKHTTPCookieStore的deleteCookie: completionHandler: 方法来操作:

    WKHTTPCookieStore *cookieStore = webview.configuration.websiteDataStore.httpCookieStore;
    [cookieStore getAllCookies:^(NSArray* cookies) {
        for (NSHTTPCookie *cookie in cookies) {
            if ([cookie.domain isEqualToString:@"jianshu.com"]) {
                [cookieStore deleteCookie:cookie completionHandler:nil];
            }
        }
    }];
    

    以上。

    相关文章

      网友评论

        本文标题:WKWebview注入Cookie和删除Cookie

        本文链接:https://www.haomeiwen.com/subject/xxyhsktx.html