44

I used to develop in android previously and i used to used SharePreference for storing user tokens. Is there anything such available in react native for both ios and android?

PuskarShestha
  • 755
  • 1
  • 7
  • 19
  • What about https://www.npmjs.com/package/react-native-shared-preferences ? – Vahagn Nahapetyan Sep 30 '18 at 16:28
  • for all other developer who looking for more weekly download and cover all platform like android, windows, Macos, Ios https://www.npmjs.com/package/@react-native-async-storage/async-storage – vibhu Jul 08 '21 at 07:21

7 Answers7

44

If you're using create-react-native-app or exp, you can use Expo.SecureStore to store your token.

import {SecureStore} from 'expo';

await SecureStore.setItemAsync('secure_token','sahdkfjaskdflas$%^&');
const token = await SecureStore.getItemAsync('secure_token');
console.log(token); // output: sahdkfjaskdflas$%^&

Details: https://docs.expo.io/versions/latest/sdk/securestore

Update in Dec 2020:

The SecureStore module is now become expo-secure-store

import * as SecureStore from 'expo-secure-store';

await SecureStore.setItemAsync('secure_token','sahdkfjaskdflas$%^&');
const token = await SecureStore.getItemAsync('secure_token');
console.log(token); // output: sahdkfjaskdflas$%^&
Calvin W
  • 569
  • 1
  • 5
  • 8
  • It worked, but I needed to install it like this "expo install expo-secure-store" and import it like this "import * as SecureStore from 'expo-secure-store'" – Dolidod Teethtard Feb 01 '20 at 15:29
  • 1
    SecureStore worked great for iOS and Android, but came up short for web in expo.io: "SecureStore.setItemAsync is not available on web" – jasonleonhard May 18 '20 at 18:44
  • Actually you can use it also in for bare React Native projects, but the installation is more involved: https://github.com/expo/expo/tree/master/packages/expo-secure-store#installation-in-bare-react-native-projects – martom Aug 27 '20 at 00:20
  • 1
    How is using `Expo.SecureStore` completely safe? It seems like if an app is the target of an XSS attack or has a vulnerable dependency, malicious code could still call `SecureStore` to let's say get the user's access token and send it to a remote server. Am I missing something in that scenario? – Alejandro Corredor May 11 '21 at 18:12
19

Here are some ways to store persistent data in React Native:

  • async-storage stores unencrypted, key-value data. Do not use Async Storage for storing Token, Secrets and other confidential data. Do use Async Storage for persisting Redux state, GraphQL state and storing global app-wide variables.

  • react-native-keychain stores username/password combination in the secure storage in string format. Use JSON.stringify/JSON.parse when you store/access it.

  • react-native-sensitive-info - secure for iOS, but uses Android Shared Preferences for Android (which is not secure by default). There is however a fork) that uses Android Keystore.

  • redux-persist-sensitive-storage - wraps react-native-sensitive-info

More info about React Native Storage & Security

kaizen
  • 1,580
  • 4
  • 26
  • 50
16

As an addition to the other answer, you might want to consider encrypting the token on the user device when storing it.

So in addition to storing it via AsyncStorage you might want to use something like: react-native-keychain to encrypt it on the device.

flaky
  • 6,816
  • 4
  • 29
  • 46
15

You might want to use AsyncStorage

Since AsyncStorage is deprecated now. You can use https://github.com/react-native-community/async-storage

Edit:

For everyone who has pointed out that AsyncStorage is not secure please refer to this post.

Sagar Acharya
  • 1,763
  • 2
  • 19
  • 38
  • 19
    This is not secure, please don't use it to store tokens or other sensitive data. – Adrian Martinez Oct 25 '18 at 10:28
  • This also seems to have issues on certain Android devices between react-native versions 0.54 & 0.57 (See https://github.com/facebook/react-native/issues/18372) – rvanlaarhoven Dec 19 '18 at 15:39
  • 1
    This answer is not complete without stating that it's not secure. Tokens, which have been specifically asked for, are usually associated with vulnerable data. For secure storage, use https://github.com/oblador/react-native-keychain. – jalooc Dec 28 '18 at 17:39
  • 3
    it is secure to save data in asyncStorage please refer to this answer https://stackoverflow.com/questions/39028755/save-sensitive-data-in-react-native – Fadi Abo Msalam Feb 08 '19 at 13:46
  • 3
    Just want to point out, asyncstorage is safe as long as the attacker doesn't have physical access to the device as well as the passcode or a trusted computer. If that's the case, the attacker can simply consume the tokens from the device anyhow. That being said, encryption couldn't hurt. – Alexander Guyer Sep 13 '19 at 15:29
  • 6
    The official React Native site says: "DON'T USE ASYNC STORAGE FOR... Token storage". Please, check here: https://reactnative.dev/docs/security#async-storage – martom Aug 27 '20 at 00:08
12

use expo-secure-store

// to install it 'expo install expo-secure-store'

import * as SecureStore from 'expo-secure-store';

const setToken = (token) => {
    return SecureStore.setItemAsync('secure_token', token);
};

const getToken = () => {
    return SecureStore.getItemAsync('secure_token');
};

setToken('#your_secret_token');
getToken().then(token => console.log(token)); // output '#your_secret_token'
Artem Bochkarev
  • 1,242
  • 13
  • 23
  • This works well, but when I'm using the web to debug I get this error -> The method or property SecureStore.setItemAsync is not available on web, are you sure you've linked all the native dependencies properly? – Paddymac Apr 05 '20 at 20:53
  • Platform Compatibility not include `web` – Iman Marashi Oct 24 '20 at 05:47
0

According to the React Native docs:

React Native does not come bundled with any way of storing sensitive data. However, there are pre-existing solutions for Android and iOS platforms.

But here are some alternatives using iOS - Keychain Services & Android - Secure Shared Preferences. See the following docs

Also, here are a few options out of the box:

Osv
  • 771
  • 8
  • 7
-1

Try this example from React Native Expo

Note: This example is for unencrypted usage so if you want secure storage so visit this page for nore information https://docs.expo.io/versions/latest/sdk/securestore

Reference: Unencrypted https://reactnavigation.org/docs/en/auth-flow.html#set-up-our-navigators Encrypted https://docs.expo.io/versions/latest/sdk/securestore

class SignInScreen extends React.Component {
  static navigationOptions = {
    title: 'Please sign in',
  };

  render() {
    return (
      <View>
        <Button title="Sign in!" onPress={this._signInAsync} />
      </View>
    );
  }

  _signInAsync = async () => {
    await AsyncStorage.setItem('userToken', 'abc');
    this.props.navigation.navigate('App');
  };
}

class HomeScreen extends React.Component {
  static navigationOptions = {
    title: 'Welcome to the app!',
  };

  render() {
    return (
      <View>
        <Button title="Show me more of the app" onPress={this._showMoreApp} />
        <Button title="Actually, sign me out :)" onPress={this._signOutAsync} />
      </View>
    );
  }

  _showMoreApp = () => {
    this.props.navigation.navigate('Other');
  };

  _signOutAsync = async () => {
    await AsyncStorage.clear();
    this.props.navigation.navigate('Auth');
  };
}

// More code like OtherScreen omitted for brevity

Maher Aldous
  • 894
  • 1
  • 10
  • 14