是否可以使用 sharedHTTPCookieStorage 为 UIWebView 手动设置 cookie?

我有一个 iOS 应用程序内部的 webview,它需要一个验证 cookie 进行正确的验证。我正在寻找一种在 iOS 应用程序的 webview 中设置 cookie 的方法,而不必发出出站请求来设置 cookie,因为我已经有客户端的认证信息了。

这个 邮寄向我们展示了 UIWebView cookie 的存储位置。

现在我正在加载一个隐藏的 web 视图来发出一个出站请求,但是我不想为了设置一个简单的 cookie 而发出一个外部请求。

89955 次浏览

编辑: 为编辑过的问题而改编

NSHTTPCookieStorage有一个 -setCookies:forURL:mainDocumentURL:方法,所以最简单的方法就是使用 NSURLConnection并实现 -connection:didReceiveResponse:,提取 cookie 并将它们放入 cookie jar:

- ( void )connection: (NSURLConnection *)connection
didReceiveResponse: (NSURLResponse *)response
{
NSHTTPURLResponse        *httpResponse = (NSHTTPURLResponse *)response;
NSArray                  *cookies;


cookies = [ NSHTTPCookie cookiesWithResponseHeaderFields:
[ httpResponse allHeaderFields ]];
[[ NSHTTPCookieStorage sharedHTTPCookieStorage ]
setCookies: cookies forURL: self.url mainDocumentURL: nil ];
}

(您也可以简单地使用 propertiesNSHTTPCookie中提取一个 NSDictionary对象,然后将字典写入磁盘。把它读回来就像使用 NSDictionary-dictionaryWithContentsOfFile:,然后用 -initWithProperties:创建 cookie 一样简单。)

然后你就可以在需要的时候把饼干从仓库里拿出来:

- ( void )reloadWebview: (id)sender
{
NSArray                 *cookies;
NSDictionary            *cookieHeaders;
NSMutableURLRequest     *request;


cookies = [[ NSHTTPCookieStorage sharedHTTPCookieStorage ]
cookiesForURL: self.url ];
if ( !cookies ) {
/* kick off new NSURLConnection to retrieve new auth cookie */
return;
}


cookieHeaders = [ NSHTTPCookie requestHeaderFieldsWithCookies: cookies ];
request = [[ NSMutableURLRequest alloc ] initWithURL: self.url ];
[ request setValue: [ cookieHeaders objectForKey: @"Cookie" ]
forHTTPHeaderField: @"Cookie" ];


[ self.webView loadRequest: request ];
[ request release ];
}

是的,您可以这样做。首先,在 applicationDidBecomeActive 中添加这一行

[[NSHTTPCookieStorage sharedHTTPCookieStorage] setCookieAcceptPolicy:NSHTTPCookieAcceptPolicyAlways];

CookieAcceptPolicy 可以在应用程序之间共享,并且可以在您不知情的情况下进行更改,因此您希望确保在每次运行应用程序时都具有所需的接受策略。

然后,设置饼干:

NSMutableDictionary *cookieProperties = [NSMutableDictionary dictionary];
[cookieProperties setObject:@"testCookie" forKey:NSHTTPCookieName];
[cookieProperties setObject:@"someValue123456" forKey:NSHTTPCookieValue];
[cookieProperties setObject:@"www.example.com" forKey:NSHTTPCookieDomain];
[cookieProperties setObject:@"www.example.com" forKey:NSHTTPCookieOriginURL];
[cookieProperties setObject:@"/" forKey:NSHTTPCookiePath];
[cookieProperties setObject:@"0" forKey:NSHTTPCookieVersion];


// set expiration to one month from now or any NSDate of your choosing
// this makes the cookie sessionless and it will persist across web sessions and app launches
/// if you want the cookie to be destroyed when your app exits, don't set this
[cookieProperties setObject:[[NSDate date] dateByAddingTimeInterval:2629743] forKey:NSHTTPCookieExpires];


NSHTTPCookie *cookie = [NSHTTPCookie cookieWithProperties:cookieProperties];
[[NSHTTPCookieStorage sharedHTTPCookieStorage] setCookie:cookie];

这个 cookie 名为 testCookie,值为 some Value123456,将随任何 http 请求发送到 www.example.com。

对于设置 cookie 的一个大的警告,请在这里看到我的问题!

应用程序退出时没有保存 NSHTTPCookieStorage 状态。有什么明确的知识/文档吗?

我们需要解决 iOS10对 cookie 的限制,这使得它们对于不同的进程来说是不可见的。

这意味着在具有多处理能力的设备上,webview 是一个与你的应用程序截然不同的过程,这意味着你的“应用程序”会话不再自动传输到 webview。

所以从本质上来说,你需要这么做(即使是之前的海报,它在 iOS10之前是自动工作的)。

在 Swift 3中,所有的键都包装在 HTTPCookiePropertyKey结构中:

let cookieProperties: [HTTPCookiePropertyKey : Any] = [.name : "name",
.value : "value",
.domain : "www.example.com",
.originURL : "www.example.com",
.path : "/",
.version : "0",
.expires : Date().addingTimeInterval(2629743)
]


if let cookie = HTTPCookie(properties: cookieProperties) {
HTTPCookieStorage.shared.setCookie(cookie)
}