【发布时间】:2019-09-15 10:04:00
【问题描述】:
我正在尝试实施 Apple 的自动填充密码。我终于让它工作了,但如果确实创建了凭据,我希望我的应用程序记住应用程序启动时的用户名/密码。我目前正在使用“KeychainSwift”窗格存储用户名和密码,但我意识到自动填充无论如何都会创建一个新的钥匙串(它们现在出现在我的 iPhone 保存的密码中),所以我不妨直接使用这些凭据。 我试着用这个来检索它,但说“没有找到匹配的项目”:
SecRequestSharedWebCredential(nil, nil){ credentials, error in
guard let credentials = credentials else { print("Keychain: No credentials found"); return }
guard error == nil else { print("Keychain Error:", error?.localizedDescription ?? "no error description"); return }
let credential: CFDictionary = unsafeBitCast(CFArrayGetValueAtIndex(credentials, i), to: CFDictionary.self)
let server = unsafeBitCast(CFDictionaryGetValue(credential, unsafeBitCast(kSecAttrServer, to: UnsafeRawPointer<Void>.self)), to: CFString.self)
let account = unsafeBitCast(CFDictionaryGetValue(credential, unsafeBitCast(kSecAttrAccount, to: UnsafeRawPointer<Void>.self)), to: CFString.self)
let password = unsafeBitCast(CFDictionaryGetValue(credential, unsafeBitCast(kSecSharedPassword, to: UnsafeRawPointer<Void>.self)), to: CFString.self)
print("Keychain OK:", server, account, password)
}
请求在第二个保护语句处停止执行,因为 'error' 不是 nil。我错过了什么吗?这有可能吗?
编辑#1: 我一直在阅读所有这些内容,并且感觉每当用户注册或登录时,我都必须单独保存/加载用户名/密码组合(通过 Keychain 或 UserDefaults)。谁能确认这是预期的行为?对我来说似乎很奇怪,因为自动填充已经将这些凭据存储在某个地方(我假设是钥匙串),因为 FaceID 会弹出并使用我在注册期间提供的正确用户名/密码自动填充文本字段。
编辑#2: 这是我最理想的目标:键盘的 QuickType 上的自动填充选项,当用户注册/登录以将其添加到设置 > 密码和帐户 > 中显示的已保存密码中时网站和应用程序密码”。也许我无法理解自动填充的实际流程,或者 iCloud 钥匙串和共享网络凭据之间的区别,但我无法理解如何实现我所需要的。
相反,发生了很多意想不到的事情(错误?):点击自动填充会自动创建新凭据,但我无法使用上面发布的代码检索它们,但如果我手动添加它SecAddSharedWebCredential() 然后我可以检索它们。为什么?它们实际上都出现在我保存的密码中,在同一个域下,具有相同的应用程序图标。此外,当 Signin ViewController 被解除(执行 Segue)时,我会收到保存密码的提示,但是当我尝试使用用户名 + 强烈建议的密码进行注册然后按下 Back(这会解除 ViewController)时,它仍然会将其添加到保存密码,这次甚至没有提示我保存密码!
我被这一切弄糊涂了,哈哈。拜托,我需要帮助:)
【问题讨论】:
-
我理解的方式是我们永远无法直接访问密码 - 这就是 Apple 实现它的方式的重点。用户可以(如果他们愿意)在文本字段等中输入密码,但我认为它们不会存储在我们可以直接访问它们的任何地方。想想开发人员仅仅能够从钥匙串中获取密码的安全隐患!
-
将用户密码保存在prefs中,使用for username作为key,当用户输入用户名并在textField中设置时访问它。
-
@ Abu,所以你建议自己存储密码,明白了。 @ siburg,我们可以直接访问密码。使用共享 Web 凭据,如果我使用 SecAddSharedWebCredential() 设置凭据,然后我可以通过调用 SecRequestSharedWebCredential() 访问密码。我只是困惑为什么我必须显式调用 SecAddSharedWebCredential() 如果它在 ViewController 被解除时自动创建凭据。
标签: ios swift nsuserdefaults keychain autofill