oblador / react-native-keychain

:key: Keychain Access for React Native
MIT License
3.12k stars 515 forks source link

[RN-Android]: Not able to retrieve credentials from App B after storing credentials from App A. #633

Open srishti-maurya opened 2 months ago

srishti-maurya commented 2 months ago

Here's a breakdown of the issue:

Step 1: Storing credentials from App A:

I successfully stored credentials (e.g., username and password) using react-native-keychain within my React Native application (let's call it App A).

Step 2: Attempting to retrieve credentials from App B:

After storing the credentials in App A, I am are trying to retrieve them from another application, let's call it App B. However, I'm encountering difficulties in retrieving the credentials using react-native-keychain.

Reference code -

  const storeData = async () => {
    const result = await Keychain.setGenericPassword(
      'credentials',
      'test_user@demo.com|test123',
      {
        service: 'com.demo.cred',
      },
    );
    console.log('🚀 ~ storeCredentials ~ result:', result);
  };

  const getData = async () => {
    const credentials = await Keychain.getGenericPassword({
      service: 'com.demo.cred',
    });
    console.log('🚀 ~ retrieveCredentials ~ credentials:', credentials);
  };

  const resetData = async () => {
    const result = await Keychain.resetGenericPassword({
      service: 'com.demo.cred',
    });
    console.log('🚀 ~ resetCredentials ~ result:', result);
  };

Note: I am able to retrieve credentials from App A after storing from App A but not able to retrieve credentials from App B. Though this flow works fine for iOS.

Setup issue -

According to the docs for linking manually https://www.npmjs.com/package/react-native-keychain#option-manually-1, I am facing issue for the below step.

package com.myapp;

+ import com.oblador.keychain.KeychainPackage;

....

public class MainActivity extends extends ReactActivity {

  @Override
  protected List<ReactPackage> getPackages() {
      return Arrays.<ReactPackage>asList(
              new MainReactPackage(),
+             new KeychainPackage()
      );
  }
  ...
}
....
import com.oblador.keychain.KeychainPackage; // --> added import here

....

public class MainApplication extends Application implements ReactApplication, DefaultLifecycleObserver {
    static Context activityContext;
    private final ReactNativeHost mReactNativeHost =
            new DefaultReactNativeHost(this) {
                @Override
                public boolean getUseDeveloperSupport() {
                    return BuildConfig.DEBUG;
                }

                @Override
                protected List<ReactPackage> getPackages() {
                    @SuppressWarnings("UnnecessaryLocalVariable")
                    List<ReactPackage> packages = new PackageList(this).getPackages();
                    // Packages that cannot be autolinked yet can be added manually here, for example:
                    // packages.add(new MyReactNativePackage());
                    packages.add(new com.ekk.motorcity.MyAppPackage());
                    packages.add(new KeychainPackage()); // --> added package here
                    return packages;
                }
....

I tried adding similarly in my App but getting error as

Native module RNKeychainManager tried to override KeychainModule. Check the getPackages() method in MainApplication.java, it might be that module is being created twice. If this was your intention, set canOverrideExistingModule=true. This error may also be present if the package is present only once in getPackages () but is also automatically added later during build time by autolinking. Try removing the existing entry and rebuild.

Attached screenshot of the error for reference

react-native-keychain-android-error

Any suggestions or fixes from the community regarding this issue with react-native-keychain, any insights or guidance would be greatly appreciated. Thank you!

iamaldi commented 1 week ago

This works as expected.

Unless otherwise specified (see below), it is the fundamental principle of isolation between applications:

Application A's data cannot be accessed by Application B, and vice versa.

On Android, you could save SharedPreferences with MODE_WORLD_READABLE and MODE_WORLD_WRITEABLE access controls. However, this was deprecated since API level 17^1 in favor of FileProvider^2.

On iOS, you can share data between application by sharing KeyChain items with a family of applications^3.