从 Flutter 应用访问 ExpoSecureStore 存储的钥匙串值 [iOS]

Access Keychain values stored by ExpoSecureStore from a Flutter app [iOS]

我有一个 ReactNative 应用程序(仅针对 iOS 发布),它使用 ExpoSecureStore 从 iOS 钥匙串中放置和读取值。

我正在过渡到 Flutter,我需要让用户保持登录状态,即从之前安装的应用程序的 RN 版本中获取他们的身份验证令牌。

所以,我是这样做的:

  1. 我从 App store 安装 RN 应用程序,
  2. 登录(令牌保存在ExpoSecureStore),
  3. 安装我的 Flutter 应用程序
  4. 尝试访问钥匙串 - 没有找到!
  5. 从应用商店重新安装 RN 应用,
  6. 打开应用程序时用户已登录!

因此,我的 Flutter 安装不会删除令牌,但无法访问它们。

2020 年 3 月 18 日更新。

这是 ReactNative 的 最新版本在 AppstoreConnect 上的样子:

这是我们的 Flutter 构建的相同信息:

我尝试将 Flutter 的 XCode 项目中的钥匙串组设置为各种值:TEAM_ID.*TEAM_ID.TEAM_ID*TEAM_ID.com.my_real_app_id 等..但没有任何帮助

有什么我遗漏的吗?

==============原题继续================

我正在使用 FlutterSecureStoragePlugin (link to the .m file) 访问钥匙串值。

这是 EXSecureStore.m 文件的 link - EXSecureStore.m on GitHub.

RN 和 Flutter 库将字符串向下传递给本机的方式有什么不同吗iOS?我想一定有一些我不知道的钥匙串访问发生了什么,所以非常欢迎任何帮助!

感谢您的阅读!

我终于解决了 expo 安全存储访问问题!

TL;DR

最重要的是你设置了相同的keychain access group,相同的kSecAttrService(钥匙串服务),当然还有你想要访问的项目的密钥。

先决条件是什么:

  • 您必须将 keychain access group 设置为与 React Native 构建中相同的值,即 TEAM_ID.*。这可以通过以下两个选项之一来实现:

    • Keychain Sharing 功能设置为 *,如下面的屏幕截图所示,
    • 打开 entitlements 文件 (project_dir/ios/Runner/Runner.entitlements) 并添加项目 $(AppIdentifierPrefix)* 项目 TEAM_ID.*keychain access groups 数组。请注意,如果您要添加第一项,则 * 之前没有 .,因为 AppIdentifierPrefix 在构建之前被转换为 TEAM_ID.Link to the apple docs on the keychain-access-groups entitlement
  • 如果您正在开发的应用具有 相同的包 ID(即它是对现有 ReactNatvie/Expo 应用的更新),您不应该在访问钥匙串项时遇到任何问题(当然,当您执行所有其他先决条件时)。 此外,如果应用具有相同的钥匙串共享组,在这种情况下TEAM_ID.*,它也应该能够访问钥匙串项目。请注意,将钥匙串访问组设置为 TEAM_ID.* 意味着只有同一开发人员(团队)开发的应用才能访问 RN 应用的钥匙串项。

  • 您必须更改 Flutter 的库(或本机 iOS)源代码,以便它 使用与 Expo 相同的钥匙串服务(kSecAttrService。对于 Expo,如果您不在 SecureStore 选项中传递 keychainService 参数,则您要写入(或获取)的项目的 kSecAttrService 属性将为 app。可以自己看here, on the expo native library's source code on GitHub (link). I made a fork of the flutter library and I will make a pull request sometime in the future, but you can just change plugin's default keychain service to app as well. It currently defaults to flutter_secure_storage_service, as seen in the plugin's source code on GitHub (link).

  • 最棘手的部分 - 因此我对上述所有步骤表示怀疑 - 是为钥匙串项目设置正确的密钥(kSecAttrAccount 我想得到。对我有帮助的是使用 Flutter 插件的 readAll 方法 (link to the native source code of readAll on GitHub)。它向我展示了钥匙串项目实际上在那里,但钥匙与 ReactNative 应用程序使用的钥匙不同。正如我通过调试发现的(它在文档中无处可寻!!!),expo 用户名和 expo 项目的名称被添加**在用于密钥的字符串**之前!因此,如果在 ReactNative 应用程序中您使用密钥 accessToken 保存令牌,它将作为 @expousername/project-name-accessToken 保存到钥匙串!它在文档中无处可寻,我不知道它是如何发生的,因为我已经查看了源代码

在我的问题中,我说过我已经将 Objective-C 代码从 expo 的库复制到 Flutter 的插件,但这不是必需的。