likes
comments
collection
share

保护您的Flutter应用程序:实现隐私屏幕

作者站长头像
站长
· 阅读数 24

保护您的Flutter应用程序:实现隐私屏幕

在当今技术驱动的世界中,隐私是应用程序开发人员最关心的问题。无论是敏感的个人信息、安全的交易细节,还是机密的企业数据,应用程序通常都会处理一些应防止被窥探的数据。

一个经常被忽视的隐私问题是任务切换器中显示的或触发截图时拍摄的应用程序快照。无意中暴露这些快照中的敏感数据会导致严重后果。

作为 Flutter 开发人员,我们有能力通过实施一项简单而有效的功能——“隐私屏幕”,将这些风险降至最低。

什么是隐私屏幕?

隐私屏幕又称安全屏幕或应用屏蔽,本质上是一个保护层,当应用处于后台或调用任务切换器时,它将覆盖应用的可见界面。该保护层可防止未经授权的用户有意或无意地查看敏感信息,从而增加了一层额外的安全保护。

为什么隐私屏幕很重要?

虽然 Android 和 iOS 等操作系统提供了管理应用程序生命周期的固有机制,但管理应用程序的数据和状态仍是开发人员的责任。在处理敏感数据时,这一点变得至关重要。

例如,银行应用程序可能会显示账户详情、交易历史或其他敏感数据。如果用户在未注销的情况下切换到另一个应用程序,这些数据就可能在应用程序切换器中被看到。实施隐私屏幕可以在不使用应用程序时隐藏这些数据,从而降低此类风险。

何时使用隐私屏幕?

你应该考虑为以下应用设置隐私屏幕:

  1. 处理敏感的用户数据,如财务信息、个人健康数据或专有业务数据。

  2. 可能在共用或公共环境中使用,因为在这种环境中,越肩窥探可能是一种风险。

在 Flutter 中实现隐私屏幕

在flutter中,隐私屏幕的实现涉及特定于平台的代码,因为Android和iOS的过程有所不同。

For android

Android 提供了一种内置机制,通过使用 WindowManager.LayoutParams.FLAG_SECURE 来确保屏幕内容的安全。该标记将窗口内容视为安全内容,止其出现在屏幕截图中或在非安全显示屏上被查看。

在我们的 flutter 应用程序中,我们可以通过编写一些 Kotlin 代码来利用这一功能,以便在需要时启用或禁用它。

让我们深入了解代码:

MainActivity.kt

import android.app.Activity
import android.content.Intent
import io.flutter.embedding.android.FlutterActivity
import io.flutter.embedding.engine.FlutterEngine
import io.flutter.plugin.common.MethodChannel
import android.view.WindowManager

class MainActivity: FlutterActivity() {
    private val CHANNEL = "security"

    override fun configureFlutterEngine(flutterEngine: FlutterEngine) {
        super.configureFlutterEngine(flutterEngine)
        setupMethodChannel(flutterEngine)
    }

    private fun setupMethodChannel(flutterEngine: FlutterEngine) {
        MethodChannel(flutterEngine.dartExecutor.binaryMessenger, CHANNEL).setMethodCallHandler { call, result ->
            when (call.method) {
                "enableAppSecurity" -> {
                    enableAppSecurity()
                    result.success(null)
                }
                "disableAppSecurity" -> {
                    disableAppSecurity()
                    result.success(null)
                }
                else -> result.notImplemented()
            }
        }
    }

    override fun onWindowFocusChanged(hasFocus: Boolean) {
        super.onWindowFocusChanged(hasFocus)
        toggleAppSecurity(hasFocus)
    }

    override fun onPause() {
        super.onPause()
        enableAppSecurity()
    }

    override fun onResume() {
        super.onResume()
        disableAppSecurity()
    }

    private fun toggleAppSecurity(hasFocus: Boolean) {
        if (hasFocus) {
            disableAppSecurity()
        } else {
            enableAppSecurity()
        }
    }

    private fun enableAppSecurity() {
        window.setFlags(WindowManager.LayoutParams.FLAG_SECURE, WindowManager.LayoutParams.FLAG_SECURE)
    }

    private fun disableAppSecurity() {
        window.clearFlags(WindowManager.LayoutParams.FLAG_SECURE)
    }
}

MainActivity 继承自 FlutterActivity,我们重载 configureFlutterEngine 函数来设置方法通道。该方法通道允许 Flutter 和 Android 之间进行通信。我们正在监听 Flutter 的两个方法 enableAppSecuritydisableAppSecurity,以切换安全标记。

toggleAppSecurity 函数会检查应用程序是否有窗口焦点。如果有焦点,我们就会禁用安全标记,否则就会启用。我们还在 onPause 函数中调用 enableAppSecurity,在 onResume 函数中调用 disableAppSecurity。这样可以确保应用程序不在前台时,应用程序内容是安全的,而当应用程序进入前台时,应用程序内容又是可见的。

通过实现这一点,当我们的应用程序的屏幕内容不在前台时,它将得到保护,增强我们的应用程序的隐私和保护敏感数据。

For iOS

与 Android 一样,iOS 也允许我们使用模糊效果来保护应用屏幕的隐私。不过,由于 iOS 和 Android 平台的不同,使用方法也略有不同。

让我们来分析一下 iOS 的实现:

AppDelegate.swift

import UIKit
import Flutter

@UIApplicationMain
@objc class AppDelegate: FlutterAppDelegate {
  private var flutterViewController: FlutterViewController!
  private var securityChannel: FlutterMethodChannel!
  private var blurEffectView: UIVisualEffectView?
  private var isInBackground: Bool = false // Track whether app is in background
  override func application(
    _ application: UIApplication,
    didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
  ) -> Bool {
    GeneratedPluginRegistrant.register(with: self)

    setupFlutterCommunication()

    return super.application(application, didFinishLaunchingWithOptions: launchOptions)
  }

  private func setupFlutterCommunication() {
    flutterViewController = window?.rootViewController as? FlutterViewController
    securityChannel = FlutterMethodChannel(
      name: "security",
      binaryMessenger: flutterViewController.binaryMessenger
    )

    securityChannel.setMethodCallHandler(handle)
  }

  override func applicationDidEnterBackground(_ application: UIApplication) {
    isInBackground = true // App entered background
    enableAppSecurity()
  }

  override func applicationDidBecomeActive(_ application: UIApplication) {
    // Check if the app was in background before becoming active
    if isInBackground {
      disableAppSecurity()
      isInBackground = false
    }
  }

  private func handle(_ call: FlutterMethodCall, result: @escaping FlutterResult) {
    switch call.method {
    case "enableAppSecurity":
      result(nil)
    case "disableAppSecurity":
      result(nil)
    default:
      result(FlutterMethodNotImplemented)
    }
  }

  private func enableAppSecurity() {
    let blurEffect = UIBlurEffect(style: .light)
    blurEffectView = UIVisualEffectView(effect: blurEffect)
    blurEffectView?.frame = window!.frame
    window?.addSubview(blurEffectView!)
  }

  private func disableAppSecurity() {
    blurEffectView?.removeFromSuperview()
  }
}

我们使用 UIApplicationMain 来表示 iOS 应用程序的入口点。这类似于 C 或 C++ 程序中的 main() 函数。AppDelegate 类继承自 FlutterAppDelegate,它允许我们访问应用程序生命周期回调和主 UIWindow

application(_:didFinishLaunchingWithOptions:) 方法中,我们初始化了 FlutterMethodChannel,以便与 Flutter 通信。我们使用 setMethodCallHanlder(_:) 来处理 Flutter 方法调用。

当应用程序进入后台时,我们会设置 isInBackground 标志并启用安全功能。这将在 applicationDidEnterBackground(_:) 方法中完成。

另一方面,当应用程序开始运行时,我们会检查它在开始运行前是否在后台。如果是,我们将禁用应用程序的安全性,并重置 isInBackground 标志。

enableAppSecurity() 函数可创建模糊效果并将其应用到 UIVisualEffectView 中,然后将其添加到窗口中。当从应用程序切换器或屏幕截图查看应用程序时,这将有效地模糊应用程序的用户界面。

disableAppSecurity() 函数只是从窗口中移除 UIVisualEffectView,从而显示应用程序的用户界面。

通过采用这种方法,我们可以确保应用程序的用户界面在不使用时受到保护,从而提高用户数据的私密性,并遵守应用程序安全的最佳实践。

Flutter集成

对于使用跨平台框架 Flutter 开发的应用程序,MethodChannels 可用于与原生 Android 和 iOS 功能进行交互。

让我们看看如何使用 Flutter 与我们在原生代码中定义的屏幕隐私功能进行交互:

platform_channel_util.dart

abstract class IAppScreenPrivacy {
  Future<void> enableScreenPrivacy();
  Future<void> disableScreenPrivacy();
}

class AppScreenPrivacyService extends IAppScreenPrivacy {
  static const platform = MethodChannel('security');
  @override
  Future<void> disableScreenPrivacy() async {
    try {
      await platform.invokeMethod('disableAppSecurity');
    } on PlatformException catch (e) {
      log('Failed to disable app security: "${e.message}"');
    }
  }

  @override
  Future<void> enableScreenPrivacy() async {
    try {
      await platform.invokeMethod('enableAppSecurity');
    } on PlatformException catch (e) {
      log('Failed to enable app security: "${e.message}"');
    }
  }
}

我们首先定义一个抽象类 IAppScreenPrivacy,该类有两个方法:enableScreenPrivacy()disableScreenPrivacy()。扩展了 IAppScreenPrivacyAppScreenPrivacyService 类实现了这些方法。

每个方法都会尝试调用本地代码中的相应函数。为此,我们使用了 MethodChannel 类的 invokeMethod 函数,并将希望调用的方法名称作为参数传递。这些名称必须与本地代码中定义的名称一致,因此我们使用了 enableAppSecuritydisableAppSecurity

如果函数调用成功,屏幕隐私设置将被应用。但是,如果出现问题,invokeMethod 调用将抛出 PlatformException 异常。该异常会被捕获并记录下来,以便调试。

通过使用这个设置,我们可以直接从我们的Flutter代码中控制我们的原生应用安全功能。这使我们能够利用本地开发的控制和力量,同时仍然受益于Flutter提供的生产力和易用性。

通过将这些安全实践集成到我们的应用程序中,我们可以更好地保护用户的敏感信息,避免通过应用程序切换器或屏幕截图不经意地暴露出来,从而确保增强用户的隐私保护。

总结

通过在 Flutter 应用程序中添加隐私屏幕,您就迈出了增强应用程序隐私和安全性的重要一步。虽然这种技术不能确保您的应用程序免受所有类型的威胁,但它在保护用户免受随意窥探方面发挥着至关重要的作用。请记住,在现代应用程序开发中,谨慎处理敏感数据并遵守最佳安全规范不是一种选择,而是一种必要。

请注意:本文仅为一般指南,根据您应用程序的具体需求,您可能需要使用更复杂的方法来保护敏感数据。请始终牢记遵守您所在地区与数据隐私相关的必要法律法规。


原文:articles.wesionary.team/securing-yo…