如何从iOS自动填充密码保存/检索密码?

问题描述 投票:0回答:2

我正在尝试实施Apple的自动填充密码。我终于得到了它的工作,但我希望我的应用程序记住应用程序启动时的用户名/密码,如果确实创建了凭据。我目前正在使用'KeychainSwift'窗格存储用户名和密码,但我意识到Autofill无论如何都会创建一个新的钥匙串(它们现在出现在我的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)。任何人都可以确认这是预期的行为吗?我觉得很奇怪,因为Autofill已经在某处保存了这些凭证(我假设了Keychain),因为FaceID弹出并使用我在注册期间提供的正确用户名/密码自动填充文本字段。

编辑#2:这是我想要理想的实现:键盘QuickType上的自动填充选项,当用户注册/将其添加到设置>密码和帐户>网站和应用程序中显示的已保存密码时密码“。也许我无法理解Autofill的实际流程,或者iCloud钥匙串和共享Web凭据之间的区别,但我无法理解如何实现我的需求。

相反,发生了许多意想不到的事情(错误?):点击自动填充会自动创建新凭据,但我无法使用上面发布的代码检索它们,但如果我手动添加SecAddSharedWebCredential(),我可以检索它们。为什么?它们实际上都出现在我保存的密码中,在相同的域下,具有相同的应用程序图标。此外,当Signin ViewController被解雇(执行Segue)时,我会收到提示保存密码,但是当我尝试使用用户名+强烈建议的密码进行注册然后按下Back(取消ViewController)时,它仍会将其添加到保存密码,这次甚至没有提示我保存密码!

我对所有这一切都很困惑。拜托,我需要帮助:)

ios swift nsuserdefaults keychain autofill
2个回答
1
投票

您不应存储用户名和密码。当用户第一次登录时,您应该生成令牌。令牌应存储在您的应用程序Keychain中。当用户第二次启动您的应用程序时,您应该使用该令牌登录。

存储令牌比存储用户名和密码更安全。

如果你想存储密码,那么至少只存储密码哈希而不是纯文本。


0
投票

快速回答:只有在您使用SecAddSharedWebCredential()手动添加密码时,才能使用自动填充保存/检索密码。

以下是我对整个过程的了解:

只需启用自动填充(将contentType设置为.username.password / .newPassword,以及添加关联域),应用程序会自动提示“保存密码?”当我正在登录或使用我自己的密码注册时,活动的ViewController被解雇(有点酷,我不需要添加任何代码来将这些凭据添加到iCloud Keychain)。但是,如果我正在注册Apple的“强密码”,当我的主动ViewController被解雇时(即通过点击后退按钮,使用interactivePopGestureRecognizer,甚至成功完成注册),它会自动将凭据添加到iCloud钥匙串甚至没有显示“保存密码?”提示(没有用户知识或同意)。我觉得这不应该发生,所以我刚刚提交了一个错误。

现在,当自动添加凭据时,我们无法使用预期的函数SecRequestSharedWebCredential(nil,nil)检索密码:将找不到凭据。如果我们用SecAddSharedWebCredential()手动添加密码,我们只能检索密码(我也觉得有点奇怪的行为,因为最终结果完全一样)。但这不是我想要的,因为SecAddSharedWebCredential()的提示不同而且太冗长,而SecRequestSharedWebCredential()也会显示提示,即使我想要静默检索它(例如,通过将用户名存储在UserDefaults中并使用SecRequestSharedWebCredential(nil, username)检索它)。

结论:我无法做我想做的事情(使用iCloud Keychain保存并静默检索正确的凭据,而无需在我自己的应用程序Keychain中复制)。我最终在我的应用程序Keychain上单独存储用户名/哈希以进行自动登录,并且我已经启用了自动填充以便快速登录,以防用户需要临时注销(从我的应用程序Keychain中删除用户名/哈希),同时保存了iCloud Keychain中的密码。

© www.soinside.com 2019 - 2024. All rights reserved.