从 Flutter 应用访问 ExpoSecureStore 存储的钥匙串值 [iOS]
Access Keychain values stored by ExpoSecureStore from a Flutter app [iOS]
我有一个 ReactNative 应用程序(仅针对 iOS 发布),它使用 ExpoSecureStore 从 iOS 钥匙串中放置和读取值。
我正在过渡到 Flutter,我需要让用户保持登录状态,即从之前安装的应用程序的 RN 版本中获取他们的身份验证令牌。
所以,我是这样做的:
- 我从 App store 安装 RN 应用程序,
- 登录(令牌保存在ExpoSecureStore),
- 安装我的 Flutter 应用程序
- 尝试访问钥匙串 - 没有找到!
- 从应用商店重新安装 RN 应用,
- 打开应用程序时用户已登录!
因此,我的 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.
Flutter 应用程序具有相同的包 ID,因此应该不是问题。
我更改了它的源代码,以便我使用相同的钥匙串服务 (kSecAttrService
),默认为 "app"
.
此外,我已经复制并修改了用于读取钥匙串值的代码,从 ExpoSecureStore.m
到 FlutterSecureStoragePlugin.m
但仍然没有运气..
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 的插件,但这不是必需的。
我有一个 ReactNative 应用程序(仅针对 iOS 发布),它使用 ExpoSecureStore 从 iOS 钥匙串中放置和读取值。
我正在过渡到 Flutter,我需要让用户保持登录状态,即从之前安装的应用程序的 RN 版本中获取他们的身份验证令牌。
所以,我是这样做的:
- 我从 App store 安装 RN 应用程序,
- 登录(令牌保存在ExpoSecureStore),
- 安装我的 Flutter 应用程序
- 尝试访问钥匙串 - 没有找到!
- 从应用商店重新安装 RN 应用,
- 打开应用程序时用户已登录!
因此,我的 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.
Flutter 应用程序具有相同的包 ID,因此应该不是问题。
我更改了它的源代码,以便我使用相同的钥匙串服务 (
kSecAttrService
),默认为"app"
.此外,我已经复制并修改了用于读取钥匙串值的代码,从
ExpoSecureStore.m
到FlutterSecureStoragePlugin.m
但仍然没有运气..
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 thekeychain-access-groups
entitlement。
- 将 Keychain Sharing 功能设置为
如果您正在开发的应用具有 相同的包 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 toapp
as well. It currently defaults toflutter_secure_storage_service
, as seen in the plugin's source code on GitHub (link).最棘手的部分 - 因此我对上述所有步骤表示怀疑 - 是为钥匙串项目设置正确的密钥(
kSecAttrAccount
) 我想得到。对我有帮助的是使用 Flutter 插件的readAll
方法 (link to the native source code ofreadAll
on GitHub)。它向我展示了钥匙串项目实际上在那里,但钥匙与 ReactNative 应用程序使用的钥匙不同。正如我通过调试发现的(它在文档中无处可寻!!!),expo 用户名和 expo 项目的名称被添加**在用于密钥的字符串**之前!因此,如果在 ReactNative 应用程序中您使用密钥accessToken
保存令牌,它将作为@expousername/project-name-accessToken
保存到钥匙串!它在文档中无处可寻,我不知道它是如何发生的,因为我已经查看了源代码
在我的问题中,我说过我已经将 Objective-C 代码从 expo 的库复制到 Flutter 的插件,但这不是必需的。