Biometric Security - Lá chắn bảo mật sinh trắc học

AI Hunter

Member
Hôm nay chúng ta sẽ cài đặt thư viện expo-local-authentication. Nó cho phép App truy cập vào FaceID (iPhone) hoặc Cảm biến vân tay (Android) của thiết bị.

Biometric Security - Lá chắn bảo mật sinh trắc học.jpg

1. Cài đặt thư viện​


Tại thư mục jarvis-mobile, chạy lệnh:

Mã:
npx expo install expo-local-authentication

2. Viết Component màn hình khóa (Lock Screen)​


Chúng ta không muốn viết đè lên code cũ quá nhiều. Hãy tạo một Component riêng cho màn hình khóa.
Mở file App.js, thêm đoạn code này vào bên trên hàm export default function App():

Thêm Import:
JavaScript:
import * as LocalAuthentication from 'expo-local-authentication'; // <--- Thư viện bảo mật
import { Lock, Unlock } from 'lucide-react-native'; // <--- Icon ổ khóa

Thêm Component AuthScreen:
JavaScript:
// Màn hình Khóa
const AuthScreen = ({ onUnlock }) => {
  const [status, setStatus] = useState('Chờ xác thực...');
  const [isError, setIsError] = useState(false);

  // Hàm gọi FaceID/Vân tay
  const authenticate = async () => {
    try {
      // 1. Kiểm tra phần cứng
      const hasHardware = await LocalAuthentication.hasHardwareAsync();
      if (!hasHardware) {
        setStatus("Thiết bị không hỗ trợ bảo mật!");
        setIsError(true);
        return;
      }

      // 2. Kiểm tra xem đã cài FaceID/Vân tay chưa
      const isEnrolled = await LocalAuthentication.isEnrolledAsync();
      if (!isEnrolled) {
        setStatus("Chưa cài đặt FaceID/Vân tay trên máy!");
        setIsError(true);
        return;
      }

      // 3. Tiến hành quét
      const result = await LocalAuthentication.authenticateAsync({
        promptMessage: 'Xác minh danh tính Stark Industries',
        fallbackLabel: 'Nhập mật khẩu dự phòng',
        disableDeviceFallback: false,
      });

      if (result.success) {
        setStatus("Xác thực thành công!");
        setTimeout(onUnlock, 500); // Đợi 0.5s rồi mở
      } else {
        setStatus("Xác thực thất bại. Thử lại.");
        setIsError(true);
      }
    } catch (e) {
      console.error(e);
      setStatus("Lỗi hệ thống.");
    }
  };

  // Tự động gọi xác thực khi mở App
  useEffect(() => {
    authenticate();
  }, []);

  return (
    <View style={styles.authContainer}>
      <StatusBar barStyle="light-content" />
      <View style={styles.authIconContainer}>
        {isError ? <Lock color="#ff0000" size={60} /> : <Lock color="#00f0ff" size={60} />}
      </View>
     
      <Text style={styles.authTitle}>STARK SECURE</Text>
      <Text style={[styles.authStatus, isError && {color: '#ff4444'}]}>{status}</Text>

      {/* Nút thử lại nếu thất bại */}
      {isError && (
        <TouchableOpacity style={styles.retryBtn} onPress={authenticate}>
          <Text style={styles.retryText}>THỬ LẠI</Text>
        </TouchableOpacity>
      )}
    </View>
  );
};

3. Tích hợp vào App chính​


Bây giờ chúng ta sửa hàm App() để nó hiển thị AuthScreen đầu tiên.

JavaScript:
export default function App() {
  // ... (Giữ nguyên các state cũ) ...
 
  // --- THÊM STATE MỚI ---
  const [isAuthenticated, setIsAuthenticated] = useState(false); // Mặc định là CHƯA ĐĂNG NHẬP

  // Nếu chưa xác thực -> Hiện màn hình khóa
  if (!isAuthenticated) {
    return <AuthScreen onUnlock={() => setIsAuthenticated(true)} />;
  }

  // Nếu đã xác thực -> Hiện App chính (Logic cũ)
  return (
    <SafeAreaView style={styles.container}>
      {/* ... (Toàn bộ code render cũ của bài trước nằm ở đây) ... */}
      {/* Bao gồm: Header, Dashboard/Chat Switcher, Bottom Nav ... */}
    </SafeAreaView>
  );
}

4. Thêm Styles cho màn hình khóa​


JavaScript:
const styles = StyleSheet.create({
  // ... Styles cũ giữ nguyên ...

  // Style cho Auth Screen
  authContainer: {
    flex: 1,
    backgroundColor: '#000',
    justifyContent: 'center',
    alignItems: 'center',
  },
  authIconContainer: {
    width: 120,
    height: 120,
    borderRadius: 60,
    borderWidth: 2,
    borderColor: '#333',
    justifyContent: 'center',
    alignItems: 'center',
    marginBottom: 30,
    backgroundColor: '#111',
  },
  authTitle: {
    color: '#fff',
    fontSize: 24,
    fontWeight: 'bold',
    letterSpacing: 4,
    marginBottom: 10,
    fontFamily: Platform.OS === 'ios' ? 'Courier' : 'monospace',
  },
  authStatus: {
    color: '#888',
    fontSize: 14,
    marginBottom: 40,
  },
  retryBtn: {
    paddingVertical: 12,
    paddingHorizontal: 40,
    backgroundColor: '#333',
    borderRadius: 25,
    borderWidth: 1,
    borderColor: '#555',
  },
  retryText: {
    color: '#fff',
    fontWeight: 'bold',
  }
});

5. Trải nghiệm thực tế​

  1. Reload App: Ngay khi App tải xong, bạn sẽ không thấy giao diện Chat nữa.
  2. Màn hình khóa: Một màn hình đen với logo Stark Secure hiện ra.
  3. Popup: Điện thoại sẽ hiện popup mặc định (FaceID hoặc Vân tay).
  4. Hành động:
    • Nếu bạn đưa mặt vào / chạm vân tay -> "Xác thực thành công" -> Vào Dashboard.
    • Nếu bạn bấm hủy hoặc đưa mặt người lạ vào -> "Xác thực thất bại" -> Nút "Thử lại" hiện ra.

Tổng kết​


Chúc mừng! Bạn đã hoàn thành lớp bảo vệ cuối cùng cho Jarvis Mobile.
Bây giờ, ứng dụng của bạn đã hội tụ đủ các yếu tố của một Super App:
  • 🧠 Thông minh: AI Chat, Vision.
  • 👂 Giao tiếp: Voice Input, TTS Output.
  • 🏠 Tiện ích: IoT Dashboard.
  • 🔐 An toàn: Biometric Auth.

Tuy nhiên, có một điểm "cấn" nhẹ.
Mỗi khi bạn mang App này sang nhà bạn bè (mạng Wifi khác), hoặc IP server thay đổi, bạn lại phải mở code ra sửa dòng const API_URL = ....
Một lập trình viên xịn không làm thế. Chúng ta cần một màn hình Settings để nhập IP server ngay trên App và lưu nó lại mãi mãi.
 
Back
Top