【问题标题】:Shared instance of NSHTTPCookieStorage does not persist cookiesNSHTTPCookieStorage 的共享实例不保留 cookie
【发布时间】:2012-07-19 05:19:27
【问题描述】:

我正在开发一个应用程序,在该应用程序中,服务器将 cookie 交给我来识别用户。

我的连续请求需要该 cookie 才能获得用户期望的响应。 我无法理解的是 NSHTTPCookieStorage 的共享实例如何以及何时丢失其 cookie。

我使用的第一个解决方案是在应用程序终止时将 cookie 从我的服务器存档并保存到用户默认值,然后在应用程序启动时从我的服务器中清除现有的 cookie 并重置我存储的那些。 在开发过程中我没有遇到问题,因为调试会话非常短,通常不需要将应用程序置于后台。

在 Beta 测试期间,问题开始了。 我带来的技巧是不仅在应用程序终止时保存 cookie,而且在将这些 cookie 交还给我的 API 调用之后保存。并且不仅在应用启动时加载保存的 cookie,而且在应用返回前台时加载。

NSHTTPCookieStorage 共享实例如何摆脱这些 cookie 以及处理它的最佳做法是什么,因为它是我的应用程序的重要组成部分,如果没有更有经验的开发人员支持,我无法相信这样一个被黑的解决方案。

提前感谢您的回答

编辑: 以下是保存/读取/清除cookies的方法

-(void)saveStoredCookies
{
    NSURL *httpUrl = @"http://myServer.com";
    NSURL *httpsUrl = @"https://myServer.com";

    NSArray *httpCookies = [[NSHTTPCookieStorage sharedHTTPCookieStorage] cookiesForURL:httpUrl];
    NSData *httpCookiesData = [NSKeyedArchiver archivedDataWithRootObject:httpCookies];
    [[NSUserDefaults standardUserDefaults] setObject:httpCookiesData forKey:@"savedHttpCookies"];

    NSArray *httpsCookies = [[NSHTTPCookieStorage sharedHTTPCookieStorage] cookiesForURL:httpsUrl];
    NSData *httpsCookiesData = [NSKeyedArchiver archivedDataWithRootObject:httpsCookies];
    [[NSUserDefaults standardUserDefaults] setObject:httpsCookiesData forKey:@"savedHttpsCookies"];

    [[NSUserDefaults standardUserDefaults] synchronize];
}

-(void)readStoredCookies
{
    //clear, read and install stored cookies
    NSURL *httpUrl = @"http://myServer.com";
    NSURL *httpsUrl = @"https://myServer.com";

    NSArray *cookies = [[NSHTTPCookieStorage sharedHTTPCookieStorage] cookiesForURL:httpUrl];
    for (NSHTTPCookie *cookie in cookies) {
        [[NSHTTPCookieStorage sharedHTTPCookieStorage] deleteCookie:cookie];
    }
    cookies = [[NSHTTPCookieStorage sharedHTTPCookieStorage] cookiesForURL:httpsUrl];
    for (NSHTTPCookie *cookie in cookies) {
        [[NSHTTPCookieStorage sharedHTTPCookieStorage] deleteCookie:cookie];
    }

    NSData *httpCookiesData = [[NSUserDefaults standardUserDefaults] objectForKey:@"savedHttpCookies"];
    if([httpCookiesData length]) {
        NSArray *savedCookies = [NSKeyedUnarchiver unarchiveObjectWithData:httpCookiesData];
        for (NSHTTPCookie *cookie in savedCookies) {
            [[NSHTTPCookieStorage sharedHTTPCookieStorage] setCookie:cookie];
        }       
    }
    NSData *httpsCookiesData = [[NSUserDefaults standardUserDefaults] objectForKey:@"savedHttpsCookies"];
    if([httpsCookiesData length]) {
        NSArray *savedCookies = [NSKeyedUnarchiver unarchiveObjectWithData:httpsCookiesData];
        for (NSHTTPCookie *cookie in savedCookies) {
            [[NSHTTPCookieStorage sharedHTTPCookieStorage] setCookie:cookie];
        }       
    }
}

-(void)clearStoredCookies
{
    NSURL *httpUrl = @"http://myServer.com";
    NSURL *httpsUrl = @"https://myServer.com";
    NSArray *cookies = [[NSHTTPCookieStorage sharedHTTPCookieStorage] cookiesForURL:httpUrl];
    for (NSHTTPCookie *cookie in cookies) {
        [[NSHTTPCookieStorage sharedHTTPCookieStorage] deleteCookie:cookie];
    }
    cookies = [[NSHTTPCookieStorage sharedHTTPCookieStorage] cookiesForURL:httpsUrl];
    for (NSHTTPCookie *cookie in cookies) {
        [[NSHTTPCookieStorage sharedHTTPCookieStorage] deleteCookie:cookie];
    }
}

【问题讨论】:

  • 请更新您用于在新请求时将 cookie 从 cookie 存储中拉出的代码。您的描述不够充分。
  • 您没有发现问题,因为您在测试期间没有从新会话之间的存储中加载 cookie。

标签: iphone ios ios5 nshttpcookie


【解决方案1】:

NSHttpCookieStorage 会丢失其 cookie,因为您没有设置 cookie 的过期时间。设置过期时间是必要的,否则当您的应用退出时,您的 cookie 将会丢失。

以下是我在应用退出和启动期间如何存储我的 cookie 的快速浏览,

NSMutableDictionary *cookieProperties = [NSMutableDictionary dictionary];
[cookieProperties setObject:name forKey:NSHTTPCookieName];
[cookieProperties setObject:strValue forKey:NSHTTPCookieValue];
[cookieProperties setObject:@"myserver.com" forKey:NSHTTPCookieDomain];    // Without http://
[cookieProperties setObject:@"myserver.com" forKey:NSHTTPCookieOriginURL]; // Without http://
[cookieProperties setObject:@"/" forKey:NSHTTPCookiePath];

// set expiration to one month from now or any future NSDate of your choice
// 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];

希望这会有所帮助。

【讨论】:

  • 我奖励了你的答案,虽然这不是我的解决方案,但它让我发现了我在代码中遗漏的东西(我使用的 URL 没有存储任何 cookie)。我现在正在度假,上完冲浪课后,我回到家已经筋疲力尽,无法触碰我的代码。当我更改某些内容时,我会编辑我的问题。
【解决方案2】:

这是模拟器吗?并使用滚动 cookie?

在模拟器中,cookie 并没有真正按照应有的方式持续存在,因为它们与桌面 Safari 共享。当 cookie 滚动时,一个最终会覆盖另一个。

这不是设备本身的问题,每个应用程序都有自己的 cookie 存储。 (而且,说实话,我还没有注意到山狮发生了这种情况。)

【讨论】:

  • 谢谢!使我免于疯狂地试图找出 cookie 没有在模拟器上持续存在的原因。
  • 天哪,你是认真的吗?...
  • 现在可能不是真的(那是 2016 年),但我转而自己处理 cookie 并且没有理由重新访问它。
【解决方案3】:

humayun 可能是对的 -

但是,您不应该将 cookie 写入 NSUserDefaults -

sharedHTTPCookieStorage 的全部意义在于您从那里读取它们。

NSArray *httpCookies = [[NSHTTPCookieStorage sharedHTTPCookieStorage] cookiesForURL:httpUrl];

出于安全原因,您甚至不能将这些 cookie 写入 NSUserDefaults。 但也许你可以。无论哪种方式,都可能没有按照humayun所说的那样设置超时。

无论哪种方式,请重构您的代码,不要尝试将 cookie 存储在用户首选项中。

【讨论】:

  • 但问题是它们不会持久保存在 sharedHTTPCookieStorage 中。我已经检查了从服务器传递的到期日期,并且设置得很好(不会在很长一段时间内到期)
【解决方案4】:

解决了!

经过一些简单的调试后,我发现问题出在我在cookiesForURL: 中使用的url。 我刚开始使用cookies 属性,现在它工作正常。

【讨论】:

  • 抱歉,我无法再访问代码了。这是 4 年前的事了。
  • @Moxy 我需要帮助
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2022-11-12
  • 2016-03-12
  • 2011-09-02
  • 1970-01-01
  • 1970-01-01
  • 2013-08-14
  • 2014-11-24
相关资源
最近更新 更多