需要某种想法在 React Native 应用程序中实现异步存储以保持用户登录应用程序

Need some sort of idea to Implementing async storage in React Native app to stay user sign in the app

各自的 Whosebug 开发者社区。大约一个月前,我是 React Native 开发的新手,我开始在 React Native 中学习和实现应用程序,现在我陷入了异步存储的困境。实际上,我使用 php 网络服务在我的应用程序中登录用户 mysql 是我正在使用的数据库。现在我想让用户登录到我的应用程序,就像用户成功登录一样,然后如果用户关闭应用程序,应用程序会存储他的用户名和密码,下次用户打开应用程序时,他不需要再次登录。应用程序直接向他显示主屏幕我读异步存储负责此类工作需要帮助来实现此类功能 我按照本教程进行登录: https://reactnativecode.com/react-native-user-login-using-php-mysql/

import React, { Component } from 'react';
 
import { StyleSheet, TextInput, View, Alert, Button, Text , AsyncStorage} from 'react-native';

// Importing Stack Navigator library to add multiple activities.
import { createStackNavigator , createAppContainer } from 'react-navigation';
 
// Creating Login Activity.
class LoginActivity extends Component {

  // Setting up Login Activity title.
  static navigationOptions =
   {
      title: 'LoginActivity',
   };
 
constructor(props) {
 
    super(props)
 
    this.state = {
 
      UserEmail: '',
      UserPassword: ''
 
    }
 
  }

UserLoginFunction = () =>{
 const { UserEmail }  = this.state ;
 const { UserPassword }  = this.state ;
 
 
fetch('http://192.168.0.107/loginrn/User_Login.php', {
  method: 'POST',
  headers: {
    'Accept': 'application/json',
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
 
    email: UserEmail,
 
    password: UserPassword
    //console.log('UserEmail')
  })
 
}).then((response) => response.json())
      .then((responseJson) => {

        // If server response message same as Data Matched
       if(responseJson === 'Data Matched')
        {

            //Then open Profile activity and send user email to profile activity.
            this.props.navigation.navigate('Second', { Email: UserEmail });

        }
        else{

          Alert.alert(responseJson);
        }

      }).catch((error) => {
        console.error(error);
      });
          
      
 
  }
 
  render() {
    return (
 
<View style={styles.MainContainer}>
 
        <Text style= {styles.TextComponentStyle}>User Login Form</Text>
  
        <TextInput
          
          // Adding hint in Text Input using Place holder.
          placeholder="Enter User Email"
 
          onChangeText={UserEmail => this.setState({UserEmail})}
 
          // Making the Under line Transparent.
          underlineColorAndroid='transparent'
 
          style={styles.TextInputStyleClass}
        />
 
        <TextInput
          
          // Adding hint in Text Input using Place holder.
          placeholder="Enter User Password"
 
          onChangeText={UserPassword => this.setState({UserPassword})}
 
          // Making the Under line Transparent.
          underlineColorAndroid='transparent'
 
          style={styles.TextInputStyleClass}
 
          secureTextEntry={true}
        />
 
        <Button title="Click Here To Login" onPress={this.UserLoginFunction} color="#2196F3" />
      
  
 
</View>
            
    );
  }
}
// Creating Profile activity.
class ProfileActivity extends Component
{

  // Setting up profile activity title.
   static navigationOptions =
   {
      title: 'ProfileActivity',
    
   };
    

   render()
   {

     const {goBack} = this.props.navigation;

      return(
         <View style = { styles.MainContainer }>
 
            <Text style = {styles.TextComponentStyle}> { this.props.navigation.state.params.Email } </Text>

            <Button title="Click here to Logout" onPress={ () => goBack(null) } />
 
         </View>
      );
   }
}

const AppNavigator= createStackNavigator(
{
   First: { screen: LoginActivity },
   
   Second: { screen: ProfileActivity }

});
export default createAppContainer(AppNavigator);

欢迎使用 Whosebug :)...

首先,如果您是 React Native 的新手,请遵循所有需要的文档部分 here

无论如何,作为一个初学者,你的代码是可以的..但正如你所知,我们正在为每个 component/screen/function 实现 类,但问题在于 React Native。在您尝试在一个文件中的一个代码库中执行所有应用程序功能的代码中。这不是最佳做法。尽可能多地通过最佳实践学习 React Native。 :)

现在让我们继续你的问题

在您的场景中,您只需添加 React Native Local Storage - AsyncStorage 即可轻松维护用户会话。用户成功登录后,您需要在用户设备中创建一些常量变量,我们可以在启动应用程序后进行检查 - 这是简单的场景。

现在开始编码

首先你需要安装@react-native-community

给出的AsyncStorage
  • 如果你用的是纱线运行这个yarn add @react-native-community/async-storage 或者如果你使用 npm 运行 这个 npm i -s @react-native-community/async-storage

  • 如果您使用的是 React Native 版本 0.60 或更高版本,则不需要 link 手动打包 npm :)

  • 如果你在 android 上 运行,你可以 运行 正常,但你在 iOS 上 运行需要安装 pod

    • cd ios && pod install
  • 现在使用

    导入AsyncStorage
    • import AsyncStorage from '@react-native-community/async-storage';
  • 之后,您需要在用户成功登录后保存用户电子邮件

    • AsyncStorage.setItem('userEmail', JSON.stringify(UserEmail));
  • 现在您可以检查逻辑 - 如果本地存储有用户电子邮件,则用户已登录

  • 但是这里你需要在用户使用AsyncStorage.clear()

  • 点击注销按钮后清除本地存储

最终代码

import React, { Component } from "react";

import {
  StyleSheet,
  TextInput,
  View,
  Alert,
  Button,
  Text,
  AsyncStorage
} from "react-native";

// Importing Stack Navigator library to add multiple activities.
import { createStackNavigator, createAppContainer } from "react-navigation";

//Import Async Storage - Local Storage
import AsyncStorage from "@react-native-community/async-storage";

// Creating Login Activity.
class LoginActivity extends Component {
  // Setting up Login Activity title.
  static navigationOptions = {
    title: "LoginActivity"
  };

  constructor(props) {
    super(props);

    this.state = {
      UserEmail: "",
      UserPassword: ""
    };
  }

  //Check If the user is already logged or not
  componentDidMount() {
    //Get User Email From Local Storage
    AsyncStorage.getItem("userEmail").then(data => {
      if (data) {
        //If userEmail has data -> email
        this.props.navigation.navigate("Second", { Email: JSON.parse(data) }); //Navigate to Second Screen
      }
    });
  }

  UserLoginFunction = () => {
    const { UserEmail } = this.state;
    const { UserPassword } = this.state;

    fetch("http://192.168.0.107/loginrn/User_Login.php", {
      method: "POST",
      headers: {
        Accept: "application/json",
        "Content-Type": "application/json"
      },
      body: JSON.stringify({
        email: UserEmail,

        password: UserPassword
        //console.log('UserEmail')
      })
    })
      .then(response => response.json())
      .then(responseJson => {
        // If server response message same as Data Matched
        if (responseJson === "Data Matched") {
          //Save User Details to Local Storage
          AsyncStorage.setItem("userEmail", JSON.stringify(UserEmail));
          //Then open Profile activity and send user email to profile activity.
          this.props.navigation.navigate("Second", { Email: UserEmail });
        } else {
          Alert.alert(responseJson);
        }
      })
      .catch(error => {
        console.error(error);
      });
  };

  render() {
    return (
      <View style={styles.MainContainer}>
        <Text style={styles.TextComponentStyle}>User Login Form</Text>

        <TextInput
          // Adding hint in Text Input using Place holder.
          placeholder="Enter User Email"
          onChangeText={UserEmail => this.setState({ UserEmail })}
          // Making the Under line Transparent.
          underlineColorAndroid="transparent"
          style={styles.TextInputStyleClass}
        />

        <TextInput
          // Adding hint in Text Input using Place holder.
          placeholder="Enter User Password"
          onChangeText={UserPassword => this.setState({ UserPassword })}
          // Making the Under line Transparent.
          underlineColorAndroid="transparent"
          style={styles.TextInputStyleClass}
          secureTextEntry={true}
        />

        <Button
          title="Click Here To Login"
          onPress={this.UserLoginFunction}
          color="#2196F3"
        />
      </View>
    );
  }
}
// Creating Profile activity.
class ProfileActivity extends Component {
  // Setting up profile activity title.
  static navigationOptions = {
    title: "ProfileActivity"
  };

  //logout button click
  logOutAction = () => {
    const { goBack } = this.props.navigation;
    AsyncStorage.clear(); // Clear the Async Storage Before Log out
    goBack(null);
  };

  render() {
    const { goBack } = this.props.navigation;

    return (
      <View style={styles.MainContainer}>
        <Text style={styles.TextComponentStyle}>
          {" "}
          {this.props.navigation.state.params.Email}{" "}
        </Text>

        <Button
          title="Click here to Logout"
          onPress={() => this.logOutAction()}
        />
      </View>
    );
  }
}

const AppNavigator = createStackNavigator({
  First: { screen: LoginActivity },

  Second: { screen: ProfileActivity }
});
export default createAppContainer(AppNavigator);

如果您有任何疑问,请随时提问 :) Happy Coding :)

在本地存储凭据并不安全。您应该考虑像这样实施基于令牌的身份验证:https://auth0.com/blog/adding-authentication-to-react-native-using-jwt/

每次用户执行需要身份验证的操作时,您应该将您的令牌作为授权传递 header 并在服务器端对其进行验证。该文档显示了如何实现它。简单又可靠。