【问题标题】:Best way for persist user authentication in react-native在 react-native 中保持用户身份验证的最佳方法
【发布时间】:2019-04-27 04:32:04
【问题描述】:

我正在尝试为用户登录编写代码并将其保留在 react-native 中。 我找到了 persist-redux 和 react 导航库。

它们是认证进度的最佳库吗? 我可以使用反应导航而不是persist-redux吗? 你能推荐我实现它的好教程吗?

【问题讨论】:

  • 您的应用程序中使用了哪种类型的身份验证?
  • 我的后端是 laravel,我正在使用令牌进行身份验证。但是你说的authenticatoin类型是什么意思?

标签: react-native react-redux


【解决方案1】:

请勿使用 AsyncStorage 存储凭据!

根据React Native's security overview,AsyncStorage 不应用于存储敏感数据,因为它是未加密的。

Async Storage 是一个社区维护的 React Native 模块,提供异步、未加密的键值对存储。应用程序之间不共享异步存储:每个应用程序都有自己的沙盒环境,并且无法访问其他应用程序的数据。

Async Storage dos and don'ts table

那我应该用什么?

您可以使用以下任何一种可能性:

来源:https://reactnative.dev/docs/security

【讨论】:

    【解决方案2】:

    您可以保存登录 AsyncStorage 时获得的身份验证令牌,并在应用启动时检查是否使用某些 api 来验证令牌。如果它有效,您可以导航到应用程序的主仪表板或您想要的任何屏幕。否则,如果登录屏幕无效,您可以导航到登录屏幕。

    你可以使用 react-navigation 作为它最推荐的库。 这是您的导航设置。

    import { createSwitchNavigator, createStackNavigator, createAppContainer } from 'react-navigation';
    
    // Implementation of HomeScreen, OtherScreen, SignInScreen, AuthLoadingScreen
    // goes here.
    
    const AppStack = createStackNavigator({ Home: HomeScreen, Other: OtherScreen });
    const AuthStack = createStackNavigator({ SignIn: SignInScreen });
    
    export default createAppContainer(createSwitchNavigator(
      {
        AuthLoading: AuthLoadingScreen,
        App: AppStack,
        Auth: AuthStack,
      },
      {
        initialRouteName: 'AuthLoading',
      }
    ));
    

    您可以在您的授权加载屏幕中编写以下代码

    import React from 'react';
    import {
      ActivityIndicator,
      AsyncStorage,
      StatusBar,
      StyleSheet,
      View,
    } from 'react-native';
    
    class AuthLoadingScreen extends React.Component {
      constructor(props) {
        super(props);
        this._bootstrapAsync();
      }
    
      // Fetch the token from storage then navigate to our appropriate place
      _bootstrapAsync = async () => {
        const userToken = await AsyncStorage.getItem('userToken');
    
        // This will switch to the App screen or Auth screen and this loading
        // screen will be unmounted and thrown away.
        this.props.navigation.navigate(userToken ? 'App' : 'Auth');
      };
    
      // Render any loading content that you like here
      render() {
        return (
          <View>
            <ActivityIndicator />
            <StatusBar barStyle="default" />
          </View>
        );
      }
    }
    

    有关更多信息,您可以随时访问此链接。

    https://reactnavigation.org/docs/en/auth-flow.html

    【讨论】:

    • 感谢您的回复。很好,但是您在此代码部分中没有使用persist-redux。是否有可能在没有严重问题的情况下完全忽略它?
    • redux-persist 非常适合用于持久存储和补水。不需要存储身份验证令牌。
    • 我在这里没有看到任何setItem。你能告诉我你从哪里得到userToken
    • 通常响应登录/注册 api。把它放在那里@roz333
    • 您好,将 oauth 令牌存储在 AsyncStorage 中是否安全?是否容易受到 XSS 和 CSRF 攻击?
    【解决方案3】:

    对于使用令牌的用户登录,您可以使用 AsyncStorage,它是 React Native 中的一项服务,允许我们在用户手机中存储少量的 sn-ps 数据。

    因此,即使用户关闭了应用程序或关闭了他们的移动设备,这会从我们的 Redux 存储中转储信息,该存储位于没有持久性的 JavaScript 内存中,我们可以查看令牌是否通过查看 AsyncStorage 存在。

    因此,如果用户至少登录一次并将令牌保存到 AsyncStorage,这将允许您保留来自不同用途或重新启动应用程序的令牌。所以要导入它,例如:

    import { AsyncStorage } from "react-native";
    import { FACEBOOK_LOGIN_SUCCESS } from "./types";
    
    export const facebookLogin = () => {};
    

    AsyncStorage 的工作方式有点像浏览器中的 localStorage。 AsyncStorage 公开了两个不同的功能,第一个称为AsyncStorage.setItem();。这可以保存一个特定的键作为第一个参数,而我们要保存的数据片段作为第二个参数,AsyncStorage.setItem('fb_token', token);。第二个函数是AsyncStorage.getItem();,我们传入您之前保存它的密钥AsyncStorage.getItem('fb_token');

    当您想将项目保存到设备时,您说这里是令牌和一个字符串,用于指定我们要将其保存为什么键。

    该密钥允许我们拥有一个单独的存储桶以保存到一个唯一位置并稍后通过查看相同的确切密钥来检索它,例如'fb_token'

    AsyncStorage 的行为与 localStorage 有点不同,因为它是一个异步操作,因此需要一些时间才能从存储中读取它。

    在记录被检索或成功保存后,AsyncStorage 将返回一个 Promise。因此,在使用 AsyncStorage 检索或保存时,您的代码必须设置为使用 Promises。

    现在,我在我的代码中使用登录 Facebook 作为示例来说明,如果您使用 Facebook 等第三方服务的身份验证,除了AsyncStorage一个。

    关键是您的代码很快就会变得一团糟。为了解决这个问题,你可以使用 ES7 Async/Await 语法来优雅地处理 Promises。

    所以使用.then() 语法,它会开始看起来像这样:

    asynchronousOperation = () => {
      myRequest().then((result) => console.log(result));
    }
    

    使用 Async/Await 语法,它看起来像这样:

    asynchronousOperation = async () => {
      let result = await myRequest();
      console.log(result);
    }
    

    所以在实践中,它会在你的动作创建器中像这样开始:

    import { AsyncStorage } from "react-native";
    import { FACEBOOK_LOGIN_SUCCESS } from "./types";
    
    export const facebookLogin = () => {
      let token = await AsyncStorage.getItem("fb_token");
      if (token) {
        // Dispatch an action saying FB login is successful
      } else {
        // Start up Facebook login process
      }
    };
    

    现在动作创建者假设你立即返回一个动作对象,对,但是AsyncStorage本质上是异步的,所以我们需要像 Redux Thunk 这样的东西,它实际上看起来像这样:

    import { AsyncStorage } from "react-native";
    import { FACEBOOK_LOGIN_SUCCESS } from "./types";
    
    export const facebookLogin = () => async dispatch => {
      let token = await AsyncStorage.getItem("fb_token");
      if (token) {
        // Dispatch an action saying FB login is successful
      } else {
        // Start up Facebook login process
      }
    };
    

    【讨论】:

    • 我一直在找这样的教程,很有意思,我在我的项目中使用了redux、redux-thunk和react-navigation,你在这里写了一个动作代码但是你没有'不为此声明任何减速器,它不需要减速器吗?
    • 还有一件事,您没有在代码中使用FACEBOOK_LOGIN_SUCCESS 类型,那么为什么要导入它?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-05-10
    • 2013-08-27
    • 2021-11-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多