使用react-native-keychain存储凭证

1,807 阅读6分钟

在本教程中,我们将向你展示如何在React Native应用中安全地存储用户凭证,并使用这些凭证来验证用户。

当你在应用中实现你的登录系统时,你需要一种方法来保存登录凭证。例如,你可能想保存一个用户登录令牌或刷新令牌,以避免在用户打开应用程序时重新输入用户名和密码。

那么问题来了,我们在哪里可以保存登录凭证?有人会说,"让我们把这些信息保存在AsyncStorage ,"但相信我,你不应该把关键信息保存在一个简单、朴素、不安全的环境中。

要在本地安全地存储信息,你应该使用react-native-keychain

想知道如何在你的React Native应用中使用 react-native-keychain吗?要理解一件事,最好的办法是通过实例来学习。

所以我们要做一个模拟登录流程的小型基本应用,它将告诉你如何安全地保存令牌并使用令牌来验证用户。

构建一个基本的用户界面

首先,让我们为登录屏幕建立一个基本的用户界面。请看下面的图片,了解我们的登录屏幕将是什么样子。

Basic UI for react-native-keychain App

一个相当基本的带有黑暗主题的登录界面(P.S.:我喜欢黑暗主题😉 )。

下面是这个用户界面的代码。

// App.js
import React from "react";
import { StyleSheet, Text, TextInput, View, Dimensions } from "react-native";

export default function App() {

  return (
    <View style={styles.container}>
        <View>
          <Text style={styles.helloText}>Hello There!</Text>
          <TextInput placeholder="email" style={styles.textInput} />
          <TextInput
            placeholder="password"
            secureTextEntry
            style={styles.textInput}
          />
          <Text style={styles.loginBtn}>
            Login
          </Text>
        </View>
    </View>
  );
}
const screenWidth = Dimensions.get("screen").width;
const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: "#1f1f1f",
    alignItems: "center",
    paddingTop: 250,
  },
  helloText: {
    color: "white",
    marginBottom: 20,
    fontSize: 30,
  },
  textInput: {
    padding: 5,
    paddingStart: 15,
    backgroundColor: "#3b3b3b",
    width: screenWidth * 0.8,
    borderRadius: 25,
    marginBottom: 15,
    color: "white",
    fontWeight: "600",
  },
  loginBtn: {
    paddingHorizontal: 25,
    paddingVertical: 10,
    backgroundColor: "#ff1178",
    borderRadius: 25,
    color: "white",
    textAlign: "center",
  }
});

安装 react-native-keychain

我们有了登录界面;现在,让我们安装钥匙链来安全地存储登录凭证。

要安装,在你项目的根目录下运行这个命令。

yarn add react-native-keychain

或者,如果你使用npm。

npm i -S react-native-keychain

安装完 react-native-keychain 后,我们可以继续实现登录系统。

实现 react-native-keychain

这个钥匙链提供了许多方法,我们可以在各种情况下使用,但为了简单起见,我们将使用三种主要方法来保存、检索和删除凭证。

这些方法是。

  • setGenericPassword
  • getGenericPassword
  • resetGenericPassword

这些方法的作用是不言而喻的。但是,我将给出一个简单的概述。

为了存储凭证,我们使用setGenericPassword 方法并传递两个参数。第一个参数是一个用户名,第二个参数是一个令牌或密码。

要读取存储的凭证的值,我们可以使用getGenericPassword 方法,不需要任何参数。

最后,要删除证书,我们可以使用没有任何参数的resetGenericPassword 方法。

让我们来存储用户的凭证。

// App.js
import React, { useEffect, useState } from "react";
import { StyleSheet, Text, TextInput, View, Dimensions } from "react-native";
import * as Keychain from "react-native-keychain";
export default function App() {
  const [isLoggedIn, setIsLoggedIn] = useState(false);
  const [userDetails, setUserDetails] = useState({});

  const handleLogin = async () => {
    // login api call here
    const token =
      "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c";
    const username = "Akshay";
    await Keychain.setGenericPassword(username, token);
    setIsLoggedIn(true);
    setUserDetails({token, username});
  };

  return (
    <View style={styles.container}>
        <View>
          <Text style={styles.helloText}>Hello There!</Text>
          <TextInput placeholder="email" style={styles.textInput} />
          <TextInput
            placeholder="password"
            secureTextEntry
            style={styles.textInput}
          />
          <Text style={styles.loginBtn} onPress={handleLogin}>
            Login
          </Text>
        </View>
    </View>
  );
}
const screenWidth = Dimensions.get("screen").width;
const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: "#1f1f1f",
    alignItems: "center",
    // justifyContent: 'center',
    paddingTop: 250,
  },
  helloText: {
    color: "white",
    marginBottom: 20,
    fontSize: 30,
  },
  textInput: {
    padding: 5,
    paddingStart: 15,
    backgroundColor: "#3b3b3b",
    width: screenWidth * 0.8,
    borderRadius: 25,
    marginBottom: 15,
    color: "white",
    fontWeight: "600",
  },
  loginBtn: {
    paddingHorizontal: 25,
    paddingVertical: 10,
    backgroundColor: "#ff1178",
    borderRadius: 25,
    color: "white",
    textAlign: "center",
  }
});

正如你所看到的,在上面的代码中,我已经创建了一个handleLogin 函数,并将其设置为登录文本的onPress

handleLogin 函数中,我们还没有实现一个完整的登录系统,但我们假设用户已经被授权,并且登录服务器返回了用户的详细信息和一个令牌。

所以,我们将把这些信息保存在安全存储中。

请注意,我们保存的是用户令牌,而不是密码本身。在客户端保存用户密码并不是一个好的做法。始终使用有一定有效期的令牌。

为了保存信息,我们使用了setGenericPassword 方法,并将用户名和令牌作为参数传递。

在成功保存后,我们正在更新我们的状态,将登录屏幕改为欢迎屏幕。

建立一个欢迎屏幕

登录后,我们将显示一个带有用户名的欢迎屏幕。我们的欢迎屏幕将看起来像这样。

Welcome Screen for react-native-keychain App

只有一条欢迎词,后面是用户名和一个注销按钮。

基于isLoggedIn 的状态变化,我们将显示一个欢迎界面并隐藏登录界面。

我们的代码将看起来像这样。

// App.js
import React, { useEffect, useState } from "react";
import { StyleSheet, Text, TextInput, View, Dimensions } from "react-native";
import * as Keychain from "react-native-keychain";
export default function App() {
  const [isLoggedIn, setIsLoggedIn] = useState(false);
  const [userDetails, setUserDetails] = useState({});
  useEffect(() => {
    (async () => {
      try {
        const credentials = await Keychain.getGenericPassword();
        if (credentials) {
          setIsLoggedIn(true);
          setUserDetails(credentials);
        } else {
          console.log("No credentials stored");
        }
      } catch (error) {
        console.log("Keychain couldn't be accessed!", error);
      }
    })();
  }, []);
  const handleLogin = async () => {
    // login api call here
    const token =
      "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c";
    const username = "Akshay";
    await Keychain.setGenericPassword(username, token);
    setIsLoggedIn(true);
    setUserDetails({token, username});
  };
  const handleLogout = async()=>{
    const logout = await Keychain.resetGenericPassword();
    console.log({logout});
    if(logout){
      setIsLoggedIn(false);
      setUserDetails({});
    }
  }
  return (
    <View style={styles.container}>
      {!isLoggedIn ? (
        <View>
          <Text style={styles.helloText}>Hello There!</Text>
          <TextInput placeholder="email" style={styles.textInput} />
          <TextInput
            placeholder="password"
            secureTextEntry
            style={styles.textInput}
          />
          <Text style={styles.loginBtn} onPress={handleLogin}>
            Login
          </Text>
        </View>
      ) : (
        <View>
          <Text style={styles.welcomeText}>
            Welcome back! {userDetails.username}
          </Text>
          <Text style={styles.logoutBtn} onPress={handleLogout} >Logout</Text>
        </View>
      )}
    </View>
  );
}
const screenWidth = Dimensions.get("screen").width;
const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: "#1f1f1f",
    alignItems: "center",
    // justifyContent: 'center',
    paddingTop: 250,
  },
  helloText: {
    color: "white",
    marginBottom: 20,
    fontSize: 30,
  },
  textInput: {
    padding: 5,
    paddingStart: 15,
    backgroundColor: "#3b3b3b",
    width: screenWidth * 0.8,
    borderRadius: 25,
    marginBottom: 15,
    color: "white",
    fontWeight: "600",
  },
  loginBtn: {
    paddingHorizontal: 25,
    paddingVertical: 10,
    backgroundColor: "#ff1178",
    borderRadius: 25,
    color: "white",
    textAlign: "center",
  },
  welcomeText: {
    color: "white",
    marginBottom: 20,
    fontSize: 30,
  },
  logoutBtn: {
    paddingHorizontal: 25,
    paddingVertical: 10,
    backgroundColor: "#ff1178",
    borderRadius: 25,
    color: "white",
    textAlign: "center",
  },
});

我们的整个代码将是这样的。

首先,我们的状态isLoggedIn 在初始阶段被设置为false 。所以,我们将显示我们的登录界面,当用户成功登录后,我们将把证书保存在安全存储中,并更新登录状态和用户细节状态。

在状态更新后,我们将显示一个带有用户名的欢迎界面和一个注销按钮。

在注销按钮上,我们添加了一个handleLogout 函数。在这个函数中,我们正在重设或从我们的安全存储中删除用户的凭证,并将我们的状态设置为初始数据。

你可能已经注意到有一个useEffect 钩子也被写入。在这个钩子中,我们正在从安全存储中检索用户的凭证,并在用户回到应用程序时根据这些信息更新状态。

如果用户将他们的信息保存在存储器中,那么我们将向他们显示欢迎界面。否则,我们将向他们显示登录界面,告诉他们他们还没有登录。

这就是你如何在不影响用户安全的情况下,轻松地存储和读取用户的凭证。

总结

在本教程中,你已经学会了如何使用react-native-keychain安全地将用户的信息保存在他们的设备上而不影响其安全性。现在你可以在你的应用程序中实现你自己的完整的登录系统。

The post Storing credentials using react-native-keychainappeared first onLogRocket Blog.