2011-05-10 126 views
69

我有一个iOS应用程序内的webviews需要一个身份验证cookie进行正确的身份验证。我正在寻找一种方法来在iOS应用程序的webview中设置一个cookie,而不必创建一个出站请求来设置cookie,因为我已经在客户端上拥有认证信息。是否可以使用sharedHTTPCookieStorage为UIWebView手动设置cookie?

post向我们展示了UIWebView cookie的存储位置。

现在我加载一个隐藏的网络视图,使呼出请求,但不希望有使设置一个简单的cookie外部请求。

回答

128

是的,你可以做到这一点。首先,在applicationDidBecomeActive加入这一行

[[NSHTTPCookieStorage sharedHTTPCookieStorage] setCookieAcceptPolicy:NSHTTPCookieAcceptPolicyAlways]; 

的cookieAcceptPolicy跨应用程序共享,可以您不知情的情况改变了,所以你要确保你有你需要你的应用程序正在运行每次接受的政策。

然后,设置Cookie:

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和价值someValue123456,可与任何HTTP请求www.example.com发送。

有关设置cookie的一个大问题,请在这里看到我的问题!

NSHTTPCookieStorage state not saved on app exit. Any definitive knowledge/documentation out there?

+0

NSHTTPCookieStorage肯定会完全实现一个持久性cookie存储。这只是在服务器端正确设置cookie生命周期的问题。 – Till 2011-05-10 19:36:21

+0

是的,它确实实现了持久cookie存储。唯一的问题是,当应用程序在Cookie设置后立即退出时,它会失败。 – kball 2011-05-10 19:47:17

+1

球,我们结束了这个解决方案,它非常接近您的答案:http://lists.apple.com/archives/Webkitsdk-dev/2003/Sep/msg00003.html – 2011-05-10 20:33:19

14

编辑:适应编辑的问题

NSHTTPCookieStorage-setCookies:forURL:mainDocumentURL:方法,所以容易的事是使用NSURLConnection和实施-connection:didReceiveResponse:,提取饼干和它们塞进饼干罐:

- (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 ]; 
} 

(你也可以简单地提取从NSHTTPCookieproperties一个NSDictionary对象,然后写字典中的磁盘。读它放回就像使用一样方便。NSDictionary-dictionaryWithContentsOfFile:,然后创建与-initWithProperties:饼干)

然后你就可以拉饼干背出存储的,当你需要它:

- (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 ]; 
} 
+1

无需手动管理NSHTTPCookieStorage这种方式。每当URL加载系统使用HTTP并且cookie接受策略设置为接受cookie时,NSHTTPCookieStorage将自动进行管理 - 如果设置为响应头,则存储Cookie,并在发送请求时设置存储的cookie的头。 – kball 2011-05-10 19:52:08

+0

当然。当然,这种方法意味着开发人员不知道每个请求会保存和发送哪些cookie,如果网站设置了不需要的跟踪cookie,这可能是不可取的。完全使用NSHTTPCookieStorage也可以是一个重量级解决方案,但通常只在Mac OS X上。例如,请参阅:http://www.cocoabuilder.com/archive/cocoa/169235-nsurlconnection-without-nshttpcookiestorage.html – 2011-05-10 20:14:26

+1

欣赏很长的答案,尽管设置一个cookie似乎有相当多的工作量。我们最终这样做了:http://lists.apple.com/archives/Webkitsdk-dev/2003/Sep/msg00003.html – 2011-05-10 20:34:36

1

有需要解决的限制对iOS的10,这使得他们看不到不同的工艺介绍饼干。

这意味着,在多处理能力的设备,网页视图是一个不同的过程,然后你的应用程序,这意味着你的“应用程序”的会话没有到网页视图自动发送了。

所以在本质上,你需要做到这一点(甚至是以前的海报,正确的,它是在iOS10之前自动工作)。

3

在斯威夫特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) 
} 
相关问题