Android/iOS平台Cordova与React Native应用间Token共享问题
同一开发者Cordova与React Native应用间双向Token共享解决方案
需求背景
需要实现同一开发者的两款应用间Token共享:
- 应用1:基于Cordova开发的遗留应用,用户登录后获取
refresh_token和access_token - 应用2:基于React Native开发
- 核心需求:用户登录应用1后将Token存入共享位置,应用2启动时检查Token是否存在,若存在则在
access_token无效时用refresh_token获取新凭证;同时需支持Cordova读取React Native存储的Token
已尝试方案
- 第三方库:评估
react-native-shared-group-preferences等库,但Android端依赖已弃用的外部存储,存在Token安全风险 - 加密标准:因Cordova与React Native默认加密转换方式不同导致解密失败,手动修改React Native实现为
RSA/ECB/PKCS1Padding以适配 - 插件维护:多数Cordova KeyStore插件已6年未更新,需手动修改Java代码支持
sharedUserId上下文,迁移期间需维护本地分支 - 原生桥接:确定React Native自定义Native Module是通过
createPackageContext安全访问Cordova SharedPreferences的可靠方式
当前状态
已实现React Native读取Cordova的Token,但无法实现Cordova读取React Native的Token
解决Cordova读取React Native Token的步骤
1. 基础配置:统一sharedUserId与签名
确保两款应用满足以下前提:
- 在各自的
AndroidManifest.xml的<manifest>标签中添加相同的sharedUserId:android:sharedUserId="com.yourcompany.shared.user" - 使用同一签名密钥打包两款应用,这是跨应用访问SharedPreferences的必要条件
2. React Native端:将Token存入共享SharedPreferences
RN默认的存储是应用私有,需自定义原生模块将Token写入可跨应用访问的SharedPreferences:
// React Native Android原生模块示例 public class SharedTokenModule extends ReactContextBaseJavaModule { private static final String SHARED_PREF_NAME = "com.yourcompany.shared_tokens"; private SharedPreferences sharedPreferences; public SharedTokenModule(ReactApplicationContext reactContext) { super(reactContext); // 初始化共享SharedPreferences sharedPreferences = reactContext.getSharedPreferences(SHARED_PREF_NAME, Context.MODE_PRIVATE); } @Override public String getName() { return "SharedTokenModule"; } // 存储Token方法,RN端可调用 @ReactMethod public void saveTokens(String accessToken, String refreshToken) { SharedPreferences.Editor editor = sharedPreferences.edit(); editor.putString("access_token", accessToken); editor.putString("refresh_token", refreshToken); editor.apply(); } // 获取Token方法,RN端可调用 @ReactMethod public void getTokens(Promise promise) { String accessToken = sharedPreferences.getString("access_token", null); String refreshToken = sharedPreferences.getString("refresh_token", null); WritableMap map = Arguments.createMap(); map.putString("access_token", accessToken); map.putString("refresh_token", refreshToken); promise.resolve(map); } }
在RN业务代码中,登录成功后调用SharedTokenModule.saveTokens()将Token存入共享存储。
3. Cordova端:自定义插件读取RN的共享Token
创建Cordova自定义插件,通过createPackageContext访问RN应用的共享SharedPreferences:
// Cordova插件Java类示例 public class SharedTokenReader extends CordovaPlugin { private static final String SHARED_PREF_NAME = "com.yourcompany.shared_tokens"; @Override public boolean execute(String action, JSONArray args, CallbackContext callbackContext) throws JSONException { if ("getSharedTokens".equals(action)) { // 替换为React Native应用的包名 Context rnAppContext = cordova.getActivity().createPackageContext( "com.yourcompany.reactnativeapp", Context.CONTEXT_IGNORE_SECURITY ); SharedPreferences sharedPreferences = rnAppContext.getSharedPreferences(SHARED_PREF_NAME, Context.MODE_PRIVATE); String accessToken = sharedPreferences.getString("access_token", null); String refreshToken = sharedPreferences.getString("refresh_token", null); JSONObject result = new JSONObject(); result.put("access_token", accessToken); result.put("refresh_token", refreshToken); callbackContext.success(result); return true; } callbackContext.error("Invalid action"); return false; } }
在Cordova的JS代码中,调用该插件的getSharedTokens()方法即可获取RN存储的Token。
4. 加密一致性保障
保持两端加密/解密逻辑完全一致:
- 继续使用
RSA/ECB/PKCS1Padding加密标准 - 确保Cordova端存储Token时的加密逻辑,与RN端解密逻辑匹配;反之亦然
内容的提问来源于stack exchange,提问作者Gabriel
相关产品推荐
相关产品推荐

