我应该将密码保存在共享的网络凭据和(本地)钥匙串中吗
Should I save passwords in shared web credentials AND (local) keychain
我正在为将与域关联的新应用程序设计登录名,即与 SPA 对应。
显然我想用
- iOS 11 密码自动填充,以及
- 共享网络凭据
我已阅读有关自动填充的文档并观看了有关它的 WWDC 视频。此外,我检查了共享 Web 凭据上的 article,我认为它比新的、重新设计的自动填充更旧。说文推荐:
Do not use the shared web credentials as your primary storage for secure user credentials. Instead, save the user’s credentials in the keychain, and only use the shared web credentials when you can’t find the login credentials in the keychain.
这让我觉得有点奇怪,因为它
- 意味着我必须涵盖更多可能的不一致,即以某种方式将钥匙串与共享的网络凭据同步(如果我在钥匙串中有凭据以及共享的网络凭据,但它们是不同的怎么办?)
- 如果我的用户卸载了我的应用程序,可能会在钥匙串中留下 "garbage"(当然我希望他们永远不会这样做,但让我们现实一点,有些人会这样做)
特别是最后一点过去一直困扰着我(在共享网络凭据和自动填充成为现实之前,或者当我的应用程序没有关联的域时)。与 macOS 不同,iOS 帐户和密码功能(在“设置”应用程序中)不会列出所有密码,而只会列出 Safari 使用的密码(即共享网络凭据),对吗? macOS 上的钥匙串访问提供了一种查看和管理所有凭据的方法,即使是那些未通过 iCloud 同步的凭据。
我明白为什么 iOS 上没有提供相同的功能,但这也意味着对于我的应用程序(本地)保存到 "its" 钥匙串的那些密码 "part" 只能是如果我在我的应用程序中为此提供 UI,则管理。如果用户在使用之前卸载了该应用程序,该项目将保留在钥匙串中,至少几年前我尝试过时是这样。
我现在的主要问题是,忽略文章的建议而仅依靠共享的网络凭据来存储密码不是更容易吗?这是他们可以在“设置”中编辑的部分(如果需要的话),它还会反映在网站上所做的任何密码更改。我会这样设计我的应用程序:
- 首次启动:应用程序在登录屏幕上启动,并通过自动填充
提供username/password
- 用户登录:应用程序在共享用户默认值中保存一个简单的标志,指示用户已登录。
- 应用重新启动,例如设备重启后:该应用程序由于标志而跳过登录屏幕,并从共享的 Web 凭据中获取密码和用户名(当然,假设用户先前已授予它权限)
- 用户明确注销:应用程序删除标志,基本上将所有内容设置回首次启动
- 用户从共享的 Web 凭据中删除用户名和密码(例如,在“设置”应用程序中或在 macOS 上使用“钥匙串访问”):应用程序一旦检测到此情况(例如,尝试远程访问时),就会返回到登录屏幕请求,或重新启动后),无论标志如何。我认为这最符合用户的意图(如果你删除了密码,你不希望某些应用程序保留它直到你注销它们)
此设置将避免钥匙串和共享网络存储中不同项目的任何问题,并且它会立即将网页中完成的更新传播到应用程序(无论如何,这正是我对我的应用程序的意图)。有什么会阻止此应用程序流程正常工作吗?
(注意:我在苹果开发者论坛上问过同样的问题,所以如果你也看到了,请不要感到困惑。我会从那里更新任何可能的答案到这里,反之亦然。)
编辑以解决@Aaron 的回答:
非常感谢您提供的信息。您的回答帮助我意识到我误解了有关共享网络凭据的一些事情:我假设对于具有关联域的应用程序,您可以访问凭据 而无需 用户交互(可能在初始授权之后)。就像您可以在应用程序请求凭据时在 macOS 上设置复选框一样。我现在意识到这是错误的,在 iOS 上你总是需要与用户核实,谢谢。
为了完整起见,我还想指出你所说的其他一些事情:
- 你是对的,我们最终会使用基于令牌的身份验证,所以我会把它保存在钥匙串中(可能除了密码之外,见下文)。一开始我只是想让问题足够简单。
- 我们的应用程序就像一个电子邮件客户端,您可以在其中更新新收到的邮件 "mail"。因此,在用户默认值之类的内容中提到的 "login flag" 只会指示应用程序是否应该像订阅收件箱一样运行。就像在 Mail 中一样,您不会期望即使在重新启动后也必须登录。
- 出于这个原因,我可能最终会将用户的密码与令牌一起保存在(本地)钥匙串中。如果令牌过期,我可以在没有用户交互的情况下请求一个新令牌,这在我们的一般网站和应用程序设计中很重要。只有当该请求失败时,我才会使用共享的 Web 凭据(在此过程中更新我的本地凭据副本)。
- 就其价值而言,您提到的最后一点可能值得商榷。例如,在 macOS 上(您可以编辑 整个 钥匙串,而不仅仅是 Safari 密码)实际上会使您退出应用程序。再次以邮件为例。如果收件箱的钥匙串项目消失了,Mail 会在下次启动时重新询问并尝试访问内容(在某种程度上实际上是 "kind of" 登录)。
再次感谢您的回答,现在我可以关闭打开的待办事项了。 :) 还要感谢@HamZa 的悬赏!
考虑这个建议:
Do not use the shared web credentials as your primary storage for secure user credentials. Instead, save the user’s credentials in the keychain, and only use the shared web credentials when you can’t find the login credentials in the keychain.
这里的主要问题是 共享网络凭据 过程有点笨拙 — 它需要用户交互并且需要时间来解析凭据。因此,如果用户已经通过您的应用程序进行了身份验证,您希望完全避免向他们显示登录页面。您可以通过将凭据存储在应用程序的钥匙串中来实现这一点,您可以在没有网络连接或用户许可的情况下立即访问它们。
这并不意味着您需要在钥匙串中存储用户的密码。通常,您会在钥匙串中存储类似 OAuth 访问令牌的内容。此令牌的存在意味着用户已通过身份验证 - 如果 API 端点拒绝您的令牌,那么您可以将它们带回登录页面。
这条建议:
User logs in: App saves a simple flag in the shared user defaults indicating the user is logged in.
可能不安全,具体取决于您隐藏在登录页面后面的内容,但通常属于用户的任何内容都需要有效的令牌才能访问,而不仅仅是用户默认值中的布尔值。
I think this matches the user intention best (if you delete a password you don't want some apps to hold onto it until you log them out)
我不同意这一点;我不希望 iOS 应用程序退出,因为我从我的 Safari 钥匙串中删除了密码。
我正在为将与域关联的新应用程序设计登录名,即与 SPA 对应。 显然我想用
- iOS 11 密码自动填充,以及
- 共享网络凭据
我已阅读有关自动填充的文档并观看了有关它的 WWDC 视频。此外,我检查了共享 Web 凭据上的 article,我认为它比新的、重新设计的自动填充更旧。说文推荐:
Do not use the shared web credentials as your primary storage for secure user credentials. Instead, save the user’s credentials in the keychain, and only use the shared web credentials when you can’t find the login credentials in the keychain.
这让我觉得有点奇怪,因为它 - 意味着我必须涵盖更多可能的不一致,即以某种方式将钥匙串与共享的网络凭据同步(如果我在钥匙串中有凭据以及共享的网络凭据,但它们是不同的怎么办?) - 如果我的用户卸载了我的应用程序,可能会在钥匙串中留下 "garbage"(当然我希望他们永远不会这样做,但让我们现实一点,有些人会这样做)
特别是最后一点过去一直困扰着我(在共享网络凭据和自动填充成为现实之前,或者当我的应用程序没有关联的域时)。与 macOS 不同,iOS 帐户和密码功能(在“设置”应用程序中)不会列出所有密码,而只会列出 Safari 使用的密码(即共享网络凭据),对吗? macOS 上的钥匙串访问提供了一种查看和管理所有凭据的方法,即使是那些未通过 iCloud 同步的凭据。
我明白为什么 iOS 上没有提供相同的功能,但这也意味着对于我的应用程序(本地)保存到 "its" 钥匙串的那些密码 "part" 只能是如果我在我的应用程序中为此提供 UI,则管理。如果用户在使用之前卸载了该应用程序,该项目将保留在钥匙串中,至少几年前我尝试过时是这样。
我现在的主要问题是,忽略文章的建议而仅依靠共享的网络凭据来存储密码不是更容易吗?这是他们可以在“设置”中编辑的部分(如果需要的话),它还会反映在网站上所做的任何密码更改。我会这样设计我的应用程序:
- 首次启动:应用程序在登录屏幕上启动,并通过自动填充 提供username/password
- 用户登录:应用程序在共享用户默认值中保存一个简单的标志,指示用户已登录。
- 应用重新启动,例如设备重启后:该应用程序由于标志而跳过登录屏幕,并从共享的 Web 凭据中获取密码和用户名(当然,假设用户先前已授予它权限)
- 用户明确注销:应用程序删除标志,基本上将所有内容设置回首次启动
- 用户从共享的 Web 凭据中删除用户名和密码(例如,在“设置”应用程序中或在 macOS 上使用“钥匙串访问”):应用程序一旦检测到此情况(例如,尝试远程访问时),就会返回到登录屏幕请求,或重新启动后),无论标志如何。我认为这最符合用户的意图(如果你删除了密码,你不希望某些应用程序保留它直到你注销它们)
此设置将避免钥匙串和共享网络存储中不同项目的任何问题,并且它会立即将网页中完成的更新传播到应用程序(无论如何,这正是我对我的应用程序的意图)。有什么会阻止此应用程序流程正常工作吗?
(注意:我在苹果开发者论坛上问过同样的问题,所以如果你也看到了,请不要感到困惑。我会从那里更新任何可能的答案到这里,反之亦然。)
编辑以解决@Aaron 的回答:
非常感谢您提供的信息。您的回答帮助我意识到我误解了有关共享网络凭据的一些事情:我假设对于具有关联域的应用程序,您可以访问凭据 而无需 用户交互(可能在初始授权之后)。就像您可以在应用程序请求凭据时在 macOS 上设置复选框一样。我现在意识到这是错误的,在 iOS 上你总是需要与用户核实,谢谢。
为了完整起见,我还想指出你所说的其他一些事情:
- 你是对的,我们最终会使用基于令牌的身份验证,所以我会把它保存在钥匙串中(可能除了密码之外,见下文)。一开始我只是想让问题足够简单。
- 我们的应用程序就像一个电子邮件客户端,您可以在其中更新新收到的邮件 "mail"。因此,在用户默认值之类的内容中提到的 "login flag" 只会指示应用程序是否应该像订阅收件箱一样运行。就像在 Mail 中一样,您不会期望即使在重新启动后也必须登录。
- 出于这个原因,我可能最终会将用户的密码与令牌一起保存在(本地)钥匙串中。如果令牌过期,我可以在没有用户交互的情况下请求一个新令牌,这在我们的一般网站和应用程序设计中很重要。只有当该请求失败时,我才会使用共享的 Web 凭据(在此过程中更新我的本地凭据副本)。
- 就其价值而言,您提到的最后一点可能值得商榷。例如,在 macOS 上(您可以编辑 整个 钥匙串,而不仅仅是 Safari 密码)实际上会使您退出应用程序。再次以邮件为例。如果收件箱的钥匙串项目消失了,Mail 会在下次启动时重新询问并尝试访问内容(在某种程度上实际上是 "kind of" 登录)。
再次感谢您的回答,现在我可以关闭打开的待办事项了。 :) 还要感谢@HamZa 的悬赏!
考虑这个建议:
Do not use the shared web credentials as your primary storage for secure user credentials. Instead, save the user’s credentials in the keychain, and only use the shared web credentials when you can’t find the login credentials in the keychain.
这里的主要问题是 共享网络凭据 过程有点笨拙 — 它需要用户交互并且需要时间来解析凭据。因此,如果用户已经通过您的应用程序进行了身份验证,您希望完全避免向他们显示登录页面。您可以通过将凭据存储在应用程序的钥匙串中来实现这一点,您可以在没有网络连接或用户许可的情况下立即访问它们。
这并不意味着您需要在钥匙串中存储用户的密码。通常,您会在钥匙串中存储类似 OAuth 访问令牌的内容。此令牌的存在意味着用户已通过身份验证 - 如果 API 端点拒绝您的令牌,那么您可以将它们带回登录页面。
这条建议:
User logs in: App saves a simple flag in the shared user defaults indicating the user is logged in.
可能不安全,具体取决于您隐藏在登录页面后面的内容,但通常属于用户的任何内容都需要有效的令牌才能访问,而不仅仅是用户默认值中的布尔值。
I think this matches the user intention best (if you delete a password you don't want some apps to hold onto it until you log them out)
我不同意这一点;我不希望 iOS 应用程序退出,因为我从我的 Safari 钥匙串中删除了密码。