NSHTTPCookieStorage在重新启动后至少解锁一次手机之前启动应用程序时会丢失cookie

时间:2014-03-25 21:32:06

标签: ios iphone cookies nsurlrequest nsurlsession

问题

正如标题所说,我目前遇到的问题是,NSHTTPCookieStorage在重启后至少解锁一次手机之前,在后台初始化时,我们的应用会丢失Cookie。

一旦cookie丢失,就无法以任何方式恢复,迫使用户重新登录以检索一组新的cookie并恢复会话。

如果在用户解锁手机后第一次注册了应用活动,那么一切都像魅力一样。

上下文

  • 我们也使用NSURLRequestNSURLSession来解决此问题 如同使用ASIHTTP和AFNetworking以及自动cookie处理一样 我们得出结论它影响整个NSHTTPCookieStorage 类。

  • 我们的应用程序有SLC(重要的位置变更监控)所以其中 在后台自动触发。

重现的步骤

  1. 制作一个执行网络呼叫的演示应用程序(“让我们称之为CALL 一个“),对服务器进行身份验证,获取一些cookie作为响应 那个。
  2. 执行需要此操作的第二次调用(让我们称之为“CALL B”) 要发送的cookie才能工作。如果一切顺利,饼干 应该自动管理并相应地发送到服务器。
  3. 让你的演示应用程序能够执行一些背景知识 示例启用SLC监视。在执行此背景 行为再次执行“CALL B”(如果它在后台任务中 是否对测试目的无关紧要)
  4. 重新启动手机,不要解锁。
  5. 等到SLC或您选择的背景行为 触发和CALL B完成。

    提示:您可以禁用并启用飞行模式以强制设备上的SLC触发器。

    问题:如果在那段时间内触发了重要的位置更改,应用程序将永久丢失所有Cookie,而无法以任何方式恢复它们。

  6. 任何帮助或想法都将受到赞赏。

2 个答案:

答案 0 :(得分:1)

似乎iOS正在使用this same issue但是存储在NSHTTPCookieStorage上的Cookie。

我已经创建了一个雷达,所以可以随意添加更多,所以这个问题在队列中被推高了一点。雷达编号为16237165。

同时,您可以执行以下解决方法:

  1. 手动处理cookie(也就是说不自动依赖iOS) 管理cookie并将其存储在NSHTTPCookieStorage中 类)。但不要使用NSUSerDefaults,因为它有。{ 同样的问题。

  2. 在手机至少解锁一次之前阻止所有网络活动。这是我们采取的选择,我们做了以下工作:

    • 使用NSFileProtectionCompleteUntilFirstUserAuthentication权限在磁盘中创建文件。
    • 在进行任何网络通话之前,请检查该应用是否能够读取该文件。如果是,则表示手机至少已解锁一次,因此您可以在不丢失Cookie的情况下拨打电话。
  3. 以下是代码示例:

    static BOOL phoneIsUnlocked = NO;

    //If this var is true, then avoid re checking if file has permissions (Cause if it was granted permissions once, it will have access now)
    if(phoneIsUnlocked) return phoneIsUnlocked;
    
    //If phone has never been unlocked, prevent all networking stuff just to make sure cookies are not lost due to an ios7 bug.
    //Creates a file with NSFileProtectionCompleteUntilFirstUserAuthentication permissions. If the app is able to read it, it means the phone was unlocked at least once after a reboot.
    
    //Get the file path
    NSString *documentsDirectory = [NSSearchPathForDirectoriesInDomains (NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
    NSString *fileName = [documentsDirectory stringByAppendingPathComponent:@"a.secure"];
    
    //create file if it doesn't exist
    if(![[NSFileManager defaultManager] fileExistsAtPath:fileName])
        [[NSFileManager defaultManager] createFileAtPath:fileName
                                                contents:[@"secure" dataUsingEncoding:NSUTF8StringEncoding]
                                              attributes:[NSDictionary dictionaryWithObject:NSFileProtectionCompleteUntilFirstUserAuthentication
                                                                                     forKey:NSFileProtectionKey]];
    
    NSFileHandle *file = [NSFileHandle fileHandleForReadingAtPath:fileName];
    phoneIsUnlocked = file != nil;     //If file is not nil, the phone has been unlocked
    [file closeFile];
    

答案 1 :(得分:0)

根据您描述的行为,NSHTTPCookieStorage使用的基础文件存储上的保护似乎已设置为"Complete until first login"

由于您无法更改NSHTTPCookieStorage存储数据的位置和方式,因此您有以下几种选择:

  1. 使用其他方法存储Cookie
  2. 检查UIApplication的{​​{3}}属性并推迟更新,直到设备解锁。您可以注册设备解锁时建议的protectedDataAvailable通知。