【问题标题】:How to store tokens in react native?如何在 React Native 中存储令牌?
【发布时间】:2018-05-18 05:19:40
【问题描述】:

我以前在 android 中开发,我曾经使用 SharePreference 来存储用户令牌。对于 ios 和 android 有什么可用的 react native 吗?

【问题讨论】:

标签: react-native


【解决方案1】:

如果您使用create-react-native-appexp,您可以使用Expo.SecureStore 来存储您的令牌。

import {SecureStore} from 'expo';

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

详情:https://docs.expo.io/versions/latest/sdk/securestore

2020 年 12 月更新:

SecureStore 模块现在变为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$%^&

【讨论】:

  • 它有效,但我需要像这样安装它“expo install expo-secure-store”并像这样导入它“import * as SecureStore from 'expo-secure-store'”
  • SecureStore 在 iOS 和 Android 上运行良好,但在 expo.io 中显示为 web 的缩写:“SecureStore.setItemAsync 在 web 上不可用”
  • 其实你也可以在裸 React Native 项目中使用它,但是安装更复杂:github.com/expo/expo/tree/master/packages/…
  • 如何使用Expo.SecureStore 完全安全?看起来如果应用程序是 XSS 攻击的目标或具有易受攻击的依赖项,恶意代码仍然可以调用SecureStore 来获取用户的访问令牌并将其发送到远程服务器。在那种情况下我错过了什么吗?
【解决方案2】:

作为另一个答案的补充,您可能需要考虑在存储令牌时在用户设备上对其进行加密。

因此,除了通过 AsyncStorage 存储它之外,您可能还想使用类似:react-native-keychain 在设备上对其进行加密。

【讨论】:

    【解决方案3】:

    以下是在 React Native 中存储持久数据的一些方法:

    • async-storage 存储未加密的键值数据。不要使用异步存储来存储 Token、Secrets 和其他机密数据。请务必使用异步存储来持久化 Redux 状态、GraphQL 状态和存储全局应用范围的变量。

    • react-native-keychain 将用户名/密码组合以字符串格式存储在安全存储中。存储/访问时使用 JSON.stringify/JSON.parse。

    • react-native-sensitive-info - 对于 iOS 是安全的,但在 Android 上使用 Android Shared Preferences(默认情况下不安全)。然而,有一个使用 Android Keystore 的fork)。

    • redux-persist-sensitive-storage - 包装 react-native-sensitive-info

    更多关于React Native Storage & Security的信息

    【讨论】:

    • 优秀的总结。
    【解决方案4】:

    您可能想使用AsyncStorage

    因为AsyncStorage 现在已被弃用。你可以使用https://github.com/react-native-community/async-storage

    编辑:

    对于所有指出 AsyncStorage 不安全的人,请参阅此post

    【讨论】:

    • 这不安全,请不要使用它来存储令牌或其他敏感数据。
    • 如果不说明它不安全,这个答案是不完整的。专门要求的令牌通常与易受攻击的数据相关联。对于安全存储,请使用github.com/oblador/react-native-keychain
    • 在 asyncStorage 中保存数据是安全的,请参考这个答案stackoverflow.com/questions/39028755/…
    • 只想指出,只要攻击者无法物理访问设备以及密码或受信任的计算机,异步存储就是安全的。如果是这种情况,攻击者无论如何都可以简单地使用设备中的令牌。话虽如此,加密也无妨。
    • React Native 官方网站说:“不要将异步存储用于...令牌存储”。请在此处查看:reactnative.dev/docs/security#async-storage
    【解决方案5】:

    使用 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'
    

    【讨论】:

    • 这很好用,但是当我使用 web 进行调试时,我得到了这个错误 -> 方法或属性 SecureStore.setItemAsync 在 web 上不可用,你确定你已经链接了所有本地依赖正确吗?
    • 平台兼容性不包括web
    【解决方案6】:

    根据React Native docs

    React Native 不捆绑任何存储敏感数据的方式。不过,已有适用于 Android 和 iOS 平台的解决方案。

    但这里有一些使用 iOS - Keychain Services & Android - Secure Shared Preferences 的替代方案。见下文docs

    此外,这里有一些开箱即用的选项:

    【讨论】:

      【解决方案7】:

      试试这个来自 React Native Expo 的例子

      注意:此示例用于未加密使用,因此如果您想要安全存储,请访问此页面以获取更多信息https://docs.expo.io/versions/latest/sdk/securestore

      参考: 未加密 https://reactnavigation.org/docs/en/auth-flow.html#set-up-our-navigators 加密 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
      
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2019-02-25
        • 2021-01-21
        • 1970-01-01
        • 2020-03-19
        • 1970-01-01
        • 2021-03-28
        • 2018-06-24
        相关资源
        最近更新 更多