草庐IT

ios - NSHTTPCookieStorage 丢失 cookie,如果应用程序在重启后手机至少解锁一次之前启动

coder 2024-01-25 原文

问题

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

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

如果应用事件是在用户解锁她/他的手机后首次注册的,那么一切都会正常进行。

上下文:

  • 我们使用 NSURLRequestNSURLSession 时也发生了这个问题 使用 ASIHTTP 和 AFNetworking 自动处理 cookie,所以 我们得出的结论是它影响了整个 NSHTTPCookieStorage 类。

  • 我们的应用程序具有 SLC(重大位置变化监控),因此它
    在后台自动触发。

重现步骤

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

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

    问题:如果在此期间触发了重大的位置更改,应用程序将永远丢失所有 cookie,没有任何机会以任何方式恢复它们。

任何帮助或想法将不胜感激。

最佳答案

似乎 iOS 有 this same issue但 cookie 存储在 NSHTTPCookieStorage 上。

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

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

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

  2. 在手机至少解锁一次之前阻止所有网络事件。这是我们选择的选项,我们执行了以下操作:

    • 使用 NSFileProtectionCompleteUntilFirstUserAuthentication 权限在磁盘中创建一个文件。
    • 在进行任何网络调用之前,请检查该应用是否能够读取该文件。如果是,则意味着手机至少解锁过一次,因此您可以在不丢失 cookie 的情况下调用电话。

这是一个代码示例:

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

关于ios - NSHTTPCookieStorage 丢失 cookie,如果应用程序在重启后手机至少解锁一次之前启动,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22646726/

有关ios - NSHTTPCookieStorage 丢失 cookie,如果应用程序在重启后手机至少解锁一次之前启动的更多相关文章

  1. ruby - 使用 Vim Rails,您可以创建一个新的迁移文件并一次性打开它吗? - 2

    使用带有Rails插件的vim,您可以创建一个迁移文件,然后一次性打开该文件吗?textmate也可以这样吗? 最佳答案 你可以使用rails.vim然后做类似的事情::Rgeneratemigratonadd_foo_to_bar插件将打开迁移生成的文件,这正是您想要的。我不能代表textmate。 关于ruby-使用VimRails,您可以创建一个新的迁移文件并一次性打开它吗?,我们在StackOverflow上找到一个类似的问题: https://sta

  2. ruby - 如何每月在 Heroku 运行一次 Scheduler 插件? - 2

    在选择我想要运行操作的频率时,唯一的选项是“每天”、“每小时”和“每10分钟”。谢谢!我想为我的Rails3.1应用程序运行调度程序。 最佳答案 这不是一个优雅的解决方案,但您可以安排它每天运行,并在实际开始工作之前检查日期是否为当月的第一天。 关于ruby-如何每月在Heroku运行一次Scheduler插件?,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/8692687/

  3. ruby-on-rails - 如果为空或不验证数值,则使属性默认为 0 - 2

    我希望我的UserPrice模型的属性在它们为空或不验证数值时默认为0。这些属性是tax_rate、shipping_cost和price。classCreateUserPrices8,:scale=>2t.decimal:tax_rate,:precision=>8,:scale=>2t.decimal:shipping_cost,:precision=>8,:scale=>2endendend起初,我将所有3列的:default=>0放在表格中,但我不想要这样,因为它已经填充了字段,我想使用占位符。这是我的UserPrice模型:classUserPrice回答before_val

  4. ruby-on-rails - 如果 Object::try 被发送到一个 nil 对象,为什么它会起作用? - 2

    如果您尝试在Ruby中的nil对象上调用方法,则会出现NoMethodError异常并显示消息:"undefinedmethod‘...’fornil:NilClass"然而,有一个tryRails中的方法,如果它被发送到一个nil对象,它只返回nil:require'rubygems'require'active_support/all'nil.try(:nonexisting_method)#noNoMethodErrorexceptionanymore那么try如何在内部工作以防止该异常? 最佳答案 像Ruby中的所有其他对象

  5. ruby - 如果指定键的值在数组中相同,如何合并哈希 - 2

    我有一个这样的哈希数组:[{:foo=>2,:date=>Sat,01Sep2014},{:foo2=>2,:date=>Sat,02Sep2014},{:foo3=>3,:date=>Sat,01Sep2014},{:foo4=>4,:date=>Sat,03Sep2014},{:foo5=>5,:date=>Sat,02Sep2014}]如果:date相同,我想合并哈希值。我对上面数组的期望是:[{:foo=>2,:foo3=>3,:date=>Sat,01Sep2014},{:foo2=>2,:foo5=>5:date=>Sat,02Sep2014},{:foo4=>4,:dat

  6. ruby - 如何在 Rails 4 中使用表单对象之前的验证回调? - 2

    我有一个服务模型/表及其注册表。在表单中,我几乎拥有服务的所有字段,但我想在验证服务对象之前自动设置其中一些值。示例:--服务Controller#创建Action:defcreate@service=Service.new@service_form=ServiceFormObject.new(@service)@service_form.validate(params[:service_form_object])and@service_form.saverespond_with(@service_form,location:admin_services_path)end在验证@ser

  7. ruby - 如何验证 IO.copy_stream 是否成功 - 2

    这里有一个很好的答案解释了如何在Ruby中下载文件而不将其加载到内存中:https://stackoverflow.com/a/29743394/4852737require'open-uri'download=open('http://example.com/image.png')IO.copy_stream(download,'~/image.png')我如何验证下载文件的IO.copy_stream调用是否真的成功——这意味着下载的文件与我打算下载的文件完全相同,而不是下载一半的损坏文件?documentation说IO.copy_stream返回它复制的字节数,但是当我还没有下

  8. ruby-on-rails - 如果我将 ruby​​ 版本 2.5.1 与 rails 版本 2.3.18 一起使用会怎样? - 2

    如果我使用ruby​​版本2.5.1和Rails版本2.3.18会怎样?我有基于rails2.3.18和ruby​​1.9.2p320构建的rails应用程序,我只想升级ruby的版本,而不是rails,这可能吗?我必须面对哪些挑战? 最佳答案 GitHub维护apublicfork它有针对旧Rails版本的分支,有各种变化,它们一直在运行。有一段时间,他们在较新的Ruby版本上运行较旧的Rails版本,而不是最初支持的版本,因此您可能会发现一些关于需要向后移植的有用提示。不过,他们现在已经有几年没有使用2.3了,所以充其量只能让更

  9. Ruby 文件 IO 定界符? - 2

    我正在尝试解析一个文本文件,该文件每行包含可变数量的单词和数字,如下所示:foo4.500bar3.001.33foobar如何读取由空格而不是换行符分隔的文件?有什么方法可以设置File("file.txt").foreach方法以使用空格而不是换行符作为分隔符? 最佳答案 接受的答案将slurp文件,这可能是大文本文件的问题。更好的解决方案是IO.foreach.它是惯用的,将按字符流式传输文件:File.foreach(filename,""){|string|putsstring}包含“thisisanexample”结果的

  10. Get https://registry-1.docker.io/v2/: net/http: request canceled while waiting - 2

    1.错误信息:Errorresponsefromdaemon:Gethttps://registry-1.docker.io/v2/:net/http:requestcanceledwhilewaitingforconnection(Client.Timeoutexceededwhileawaitingheaders)或者:Errorresponsefromdaemon:Gethttps://registry-1.docker.io/v2/:net/http:TLShandshaketimeout2.报错原因:docker使用的镜像网址默认为国外,下载容易超时,需要修改成国内镜像地址(首先阿里

随机推荐