We are building a React Native app for iOS and we are using an internal API built on node + express + jsonwebtoken.
When the user logs in with username/password, the server validates those credentials and sends the client back a JSON web token that they must then send along with every API request. So the React native app must store this token.
How do I securely store this client token in the React native app? Is it necessary to take any additional steps besides just storing the token in a variable?
Keychain Services allows you to securely store small chunks of sensitive info for the user. This is an ideal place to store certificates, tokens, passwords, and any other sensitive information that doesn't belong in Async Storage.
For iOS, you'd store that in the keychain... https://auth0.com/docs/libraries/lock-ios/save-and-refresh-jwt-tokens
Here's a couple ways of doing that in react native that I found. There may be others. There may be better options. This is just what I found quickly.
https://github.com/search?utf8=%E2%9C%93&q=react-native+keychain
For Android, you'd store that in either the SharedPreferences or maybe even better the KeyStore since it's encrypted there.
I recently built a keychain manager in react-native so I may be able to help you.
NOTE: This solution does require that your app be running on expo.
To encrypt and store your tokens locally on the device you can use a package called expo-secure-store.
This will give you easy access to the iOS keychain and android keystore system and can be implemented as below:
import * as SecureStore from "expo-secure-store";
/**
* Saves the value to the ios keychain or Android keystore
* @param {string} key => the key you want to save the value for
* @param {any} value => the value you want to encrypt
* @return => A promise that will reject if value cannot be stored on the device.
*/
SecureStore.setItemAsync(key, value);
/**
* Fetches the value from the keychain/keystore for the specified key
* @param {string} key => the key you set for the value
* @returns {any} => A promise that resolves to the previously stored value, or null if there is no entry for the given key.
* The promise will reject if an error occurred while retrieving the value.
*/
SecureStore.getItemAsync(key);
/**
* Saves the value to the ios keychain or Android keystore
* @param {string} key => the key you want to save the value for
* @param {any} value => the value you want to encrypt
* @return => A promise that will reject if value cannot be stored on the device.
*/
SecureStore.deleteItemAsync(key);
To be app agnostic, I would store it using ASyncStorage. In fact I am testing this on a new project.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With