7

I'm trying to figure out a secure way to persist session in react native.

I have some sensitive data like access token retrieved from server that i'm planning to set to the redux state.

I'm not sure if it is safe to set sensitive data like accessToken to redux state.

If not safe, should i save the accessToken to device storage like react-native-keychain and load the accessToken on every screen request and server request?

dispatch({type: LOGIN_SUCCESS, payload: {refreshToken, authTimestamp, email} });
const INITIAL_STATE = {    
    token: {      
        accessToken: '',          
        loading: false,
        error: ''
    }
};
kaizen
  • 1,580
  • 4
  • 26
  • 50
  • 1
    Yes, It's safe. But I want to add some comments: I think redux state doesn't store it (unless you use redux-state-persist), means, you will loose the access token when you exit app. In case you want to store it (so user doesn't have to login again), I suggest store it in react-native-keychain, read from it and set to state when app started – Tran Quan Jul 14 '20 at 07:26
  • Hi, i have the `refreshToken` and `accessToken` stored in mongoDB, i'm confused if i should store both in the `react-native-keychain`. Or only store `refreshToken` to `react-native-keychain` then load the `accessToken` to redux state. The `refreshToken` and `accessToken` are stored in mongoDB. `newUser.refreshToken = await newUser._id.toString()+ '.' + crypto.randomBytes(64).toString('hex'); newUser.accessToken = newUser._id.toString()+ '.' + crypto.randomBytes(64).toString('hex');` – kaizen Jul 14 '20 at 07:53

1 Answers1

5

Yes you should be saving the accessToken in device secured storage, if you plan on storing it at all. The refreshTokens likely should never leave your server as that is possible security vulnerability for the continual generation of new accessTokens.

You can load the accessToken everytime. Another alternative would be to store the accessToken in a secure cookie and pass that back to the app, then you wouldn't have to worry about the management of the tokens at all.

Then there is a question of how you are going to populate that, usually you integrate with an authentication service and an authorization provider. These are two different additional steps to secure your app. I assume you already have off the shelf solutions (if not make a comment and I'll add some examples here)

Warren Parad
  • 3,910
  • 1
  • 20
  • 29
  • Hi, i'm currently following the flow from this guide https://medium.com/@rossbulat/react-native-user-authentication-flow-explained-d988905ba106 – kaizen Jul 15 '20 at 00:32
  • i'm thinking if i should save the `refreshToken(expires in 6months)` to the device storage and use the `refreshToken` to generate an `accessToken(expires in 20mins)`. Both `refreshToken` and `accessToken` will be stored in mongoDB and also device storage. The express server's protected route will compare and check expiration if the `accessToken(expires in 20mins)` in device storage matches the one in user's mongoDB `accessToken`. – kaizen Jul 15 '20 at 00:38
  • i'm not sure if my approach of having `refreshToken` and `accessToken` is redundant, since it will still need to validate with the server for every request that requires access token validation. – kaizen Jul 15 '20 at 00:45
  • i'm also looking for a solution to validate tokens securely both on native app and web. For native app, i use `DeviceInfo.getUniqueId()` from `react-native-device-info` npm to check if the user is the owner of the token. For web, it seems like there is no way to get unique device id that does not change. Both IP and MAC address can be altered. – kaizen Jul 15 '20 at 01:00
  • 2
    I will repeat this, the `refresh token` should never be sent to the device. – Warren Parad Jul 16 '20 at 09:12