代码之家  ›  专栏  ›  技术社区  ›  Gero

我应该在共享web凭据和(本地)密钥链中保存密码吗

  •  12
  • Gero  · 技术社区  · 7 年前

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

    • iOS 11密码自动填充,以及
    • 共享Web凭据

    我阅读了有关autofill的文档,并观看了WWDC的视频。此外,我检查了 article 在共享的Web凭据上,我认为它比新的、经过修改的autofill旧。上述文章建议:

    不要将共享web凭据用作安全用户凭据的主存储。相反,将用户的凭据保存在密钥链中,并且仅当您在密钥链中找不到登录凭据时才使用共享web凭据。

    这让我觉得有点奇怪,因为 -意味着我必须覆盖更多可能的不一致,即以某种方式将密钥链与共享的web凭据同步(如果我在密钥链中有凭据以及共享的web凭据,但它们不同呢?) -如果我的用户卸载我的应用程序,可能会在钥匙链中留下“垃圾”(当然,我希望他们永远不会这样做,但现实一点,有些人会这样做)

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

    我理解为什么iOS上没有提供相同的密码,但这也意味着,对于我的应用程序保存(本地)到“其”钥匙链“部分”的密码,只有在我的应用程序中为其提供UI时,才能对其进行管理。如果用户在使用该应用程序之前卸载了该应用程序,则该项目将保留在钥匙链中,至少几年前我尝试时是这样。

    我现在的主要问题是,无视文章的建议,只依赖共享的web凭据来存储密码,不是更容易吗?这是他们可以在设置中编辑的部分(如果需要的话),它也将反映网站上所做的任何密码更改。我会这样设计我的应用程序:

    • 首次启动:应用程序在登录屏幕上启动,并通过自动填充提供用户名/密码
    • 用户登录:应用程序在共享用户默认值中保存一个简单标志,指示用户已登录。
    • 应用程序会重新启动,例如在设备重新启动后:应用程序会由于标记跳过登录屏幕,并从共享的web凭据中获取密码和用户名(当然,假设用户之前授予了它权限)
    • 用户显式注销:应用程序删除标志,基本上将所有内容设置回第一次启动
    • 用户从共享的web凭据中删除用户名和密码(例如,在设置应用程序中或在macOS上使用Keychain访问):应用程序一旦检测到这一点(例如,在尝试远程请求时,或在重新启动后),无论标志如何,都会立即返回登录屏幕。我认为这最符合用户的意图(如果你删除了密码,你不希望某些应用程序在你注销之前保留密码)

    此设置将避免钥匙链和共享web存储中不同项目的任何问题,并将立即将网页中所做的更新传播到应用程序(这也是我对我的应用程序的意图)。是否有任何东西会阻止此应用程序流工作?

    (注意:我在苹果开发者论坛上问了同样的问题,所以如果你也看到了,请不要感到困惑。我将从这里更新所有可能的答案,反之亦然。)


    编辑地址@Aaron的答案:

    非常感谢您提供的信息。您的回答帮助我意识到我误解了共享web凭据的某些内容:我假设对于具有关联域的应用程序,您可以访问凭据 没有 用户交互(可能在初始授权之后)。例如,当应用程序请求凭据时,可以在macOS上设置复选框。我现在意识到这是错误的,在iOS上,您必须始终与用户进行验证,谢谢。

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

    • 您是对的,我们最终将使用基于令牌的身份验证,因此我将把它保存在密钥链中(可能除了密码之外,请参见下文)。一开始我只是想让这个问题足够简单。
    • 我们的应用程序就像一个电子邮件客户端,您可以在其中更新新的传入“邮件”。因此,用户默认设置中提到的“登录标志”只是指示应用程序是否应该像订阅收件箱一样运行。就像在Mail中一样,即使在重新启动后,您也不需要登录。
    • 因此,我可能最终会将用户的密码与令牌一起保存在(本地)密钥链中。如果令牌过期,我可以在没有用户交互的情况下请求一个新的令牌,这在我们的一般网站和应用程序设计中很重要。只有当该请求失败时,我才会使用共享的web凭据(在此过程中更新我的本地Cred副本)。
    • 你提到的最后一点可能值得商榷。例如,在macOS上(您可以在其中编辑 全部的 钥匙链,而不仅仅是Safari密码)实际上会让你退出应用程序。再次以邮件为例。如果收件箱的钥匙链项目不见了,邮件会在下次启动时重新询问,并尝试访问内容(从某种程度上说,这实际上是一种“登录”)。

    再次感谢您的回答,现在我可以结束一个开放的待办事项了。:)还要感谢@HamZa提供的悬赏!

    1 回复  |  直到 7 年前
        1
  •  8
  •   Aaron Brager    7 年前

    考虑到这一建议:

    不要将共享web凭据用作安全用户凭据的主存储。相反,请将用户凭据保存在密钥链中,并且仅在密钥链中找不到登录凭据时使用共享web凭据。

    这里的主要问题是 共享web凭据 这个过程有点笨拙,它需要用户交互,并且需要时间来解析凭据。因此,如果用户已经使用你的应用程序进行了身份验证,那么你要避免向他们显示登录页面。您可以通过将凭据存储在应用程序的钥匙链中来实现这一点,您可以在无需网络连接或用户许可的情况下立即访问凭据。

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

    此建议:

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

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


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

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