我应该在共享网络凭据和(本地)钥匙串

时间:2018-01-30 08:49:42

标签: ios keychain shared

我正在设计一个与域名相关联的新应用程序的登录,即与SPA的对应物。 显然我想用

  • iOS 11密码自动填充和
  • 共享网站凭据

我已阅读有关自动填充的文档,并观看了有关它的WWDC视频。另外,我检查了共享Web凭据上的article,我认为它比新的,重新设计的自动填充更早。文章建议:

  

请勿将共享Web凭据用作安全用户凭据的主存储。相反,请将用户的凭据保存在钥匙串中,并且只有在密钥链中找不到登录凭据时才使用共享的Web凭据。

这让我有些奇怪,因为它   - 意味着我必须涵盖更多可能的不一致性,即以某种方式将密钥链与共享的Web凭证同步(如果我在密钥链中有凭据以及共享的Web凭据,但它们会有什么不同?)   - 潜在地离开"垃圾"如果我的用户用户卸载了我的应用程序(我自然希望他们不会做到这一点,但是让我们变得现实,有些人会这样做)

特别是最后一点在过去一直困扰着我(在共享网络凭据和自动填充之前,或者当我的应用程序没有关联的域时)。与macOS不同,iOS帐户&密码功能(在“设置”应用中)不会列出所有密码,但只列出Safari使用的密码(即共享的网络凭据),对吗? MacOS上的Keychain Access提供了一种查看和管理所有凭证的方法,即使是那些不通过iCloud同步的凭证。

我理解为什么在iOS上没有提供同样的功能,但它也意味着我的应用程序保存(本地)到#34;它的"钥匙串"部分"只有在我的应用程序中为此提供UI时才能进行管理。如果用户在使用之前卸载了该应用程序,该项目将保留在钥匙串中,至少在几年前我尝试过时就是这样。

我现在的主要问题是,忽略文章的建议并且仅依靠共享的网络凭据进行密码存储会更容易吗?这是他们可以在“设置”中编辑的部分(如果需要),它也会反映网站上所做的任何密码更改。我会像这样设计我的应用程序:

  • 首次启动:应用程序在“登录”屏幕上启动,并通过“自动填充”提供用户名/密码
  • 用户登录:应用程序在共享用户默认值中保存一个简单标志,表示用户已登录。
  • App重新启动,例如设备重启后:应用程序因标志而跳过登录屏幕,并从共享的Web凭据中获取密码和用户名(当然,假设用户先前已授予其权限)
  • 用户明确注销:该应用删除该标志,基本上将所有内容设置为首次启动
  • 用户从共享的Web凭据中删除用户名和密码(例如,在“设置”应用程序中或使用macOS上的“Keychain Access”):应用程序一检测到这一点就会回退到登录屏幕(例如,在尝试远程请求时,或重新启动后),无论旗帜如何。我认为这最符合用户意图(如果你删除了一个密码,你不想要一些应用程序保留它,直到你注销它们为止)

这种设置可以避免钥匙串和共享网络存储中不同项目的任何问题,并且它会立即将网页中完成的更新传播到应用程序(这也是我对我的应用程序的意图)。有什么东西可以阻止这个应用程序流动吗?

(注意:我在苹果开发人员论坛上提出了同样的问题,所以如果你看到这一点也不要混淆。我会从那里更新任何可能的答案,反之亦然。)

编辑以解决@ Aaron的答案:

非常感谢您提供的信息。您的回答帮助我意识到我误解了共享Web凭据的一些内容:我认为对于具有关联域的应用程序,您可以访问凭据而无需用户交互(可能是初始授权之后)。就像您可以在应用程序请求凭据时在macOS上设置复选框。我现在意识到这是错误的,在iOS上你总是需要与用户核实,谢谢。

为了完整起见,我还想指出你说的其他一些事情:

  • 你是对的,我们最终将使用基于令牌的身份验证,因此我会将其保存在钥匙串中(可能除了密码之外,请参见下文)。我刚开始试着让这个问题变得简单。
  • 我们的应用就像一个电子邮件客户端,您可以在其中更新新收到的邮件"。提到的"登录标志"因此,用户默认值只会指示应用程序是否应该像订阅收件箱一样。就像在Mail中一样,即使重新启动,你也不会想要登录。
  • 出于这个原因,我最终可能会将用户的密码与令牌一起保存在(本地)钥匙串中。如果令牌过期,我可以在没有用户交互的情况下请求新的令牌,这在我们的常规网站和应用程序设计中非常重要。只有当该请求失败时,我才会使用共享的Web凭据(在此过程中更新我的本地信用副本)。
  • 对于它的价值,你提到的最后一点可能是值得商榷的。例如,在macOS上(您可以编辑整个钥匙串,而不仅仅是Safari密码)事实上会将您从应用程序中注销。再次邮件,作为一个例子。如果收件箱的钥匙串项目消失,Mail会在下次启动时重新询问并尝试访问内容(实际上是"某种方式的登录方式)。

再次,非常感谢你的回答,现在我可以关闭一个开放的待办事项。 :)还要感谢@HamZa给予赏金!

1 个答案:

答案 0 :(得分:4)

考虑这个建议:

  

请勿将共享Web凭据用作安全用户凭据的主存储。相反,请将用户的凭据保存在钥匙串中,并且只有在密钥链中找不到登录凭据时才使用共享的Web凭据。

这里的主要问题是共享Web凭据进程有点笨拙 - 它需要用户交互并需要时间来解析凭据。因此,如果用户已经使用您的应用进行了身份验证,则您希望避免向他们显示登录页面。您可以通过在应用程序的钥匙串中存储凭据来实现此目的,您可以在没有网络连接或用户权限的情况下立即访问它们。

这并不意味着您需要将用户的密码存储在钥匙串中。通常,您会在钥匙串中存储类似OAuth访问令牌的内容。此令牌的存在意味着用户已通过身份验证 - 如果API端点拒绝您的令牌,则可以将其带回登录页面。

这个建议:

  

用户登录:应用程序在共享用户默认值中保存一个简单标志,表示用户已登录。

可能不安全,具体取决于您在登录页面后面隐藏的内容,但通常属于该用户的任何内容都应该要求访问有效令牌,而不仅仅是用户默认值中的bool。

  

我认为这最符合用户意图(如果你删除了一个密码,你不希望某些应用程序在你注销之前保留它)

我不同意这一点;我不希望iOS应用程序退出,因为我从Safari密钥链中删除了密码。