在 flutter 应用程序中存储 API 凭据

Storing API credentials in a flutter application

我在我的 flutter 应用程序中使用 googleapis 服务,它需要一些 JSON 格式的凭据。在我的应用程序中存储此凭据的最佳方式是什么?

我可以在资产文件夹中保留一个 JSON 文件并在我的主函数中读取它吗?

或者我应该在我的主要功能中对凭据进行硬编码吗?我是 flutter 开发的新手。

我的代码如下所示

import 'package:googleapis/storage/v1.dart';
import 'package:googleapis_auth/auth_io.dart';

final _credentials = new ServiceAccountCredentials.fromJson(r'''
{
  "private_key_id": ...,
  "private_key": ...,
  "client_email": ...,
  "client_id": ...,
  "type": "service_account"
}
''');

const _SCOPES = const [StorageApi.DevstorageReadOnlyScope];

void main() {
  clientViaServiceAccount(_credentials, _SCOPES).then((http_client) {
    var storage = new StorageApi(http_client);
    storage.buckets.list('dart-on-cloud').then((buckets) {
      print("Received ${buckets.items.length} bucket names:");
      for (var file in buckets.items) {
        print(file.name);
      }
    });
  });
}

我应该在哪里保存以下凭据:

{
  "private_key_id": ...,
  "private_key": ...,
  "client_email": ...,
  "client_id": ...,
  "type": "service_account"
}

我不认为像上面这样的硬编码是个好主意。

我认为这应该可行:https://medium.com/@sokrato/storing-your-secret-keys-in-flutter-c0b9af1c0f69

谢谢。

要存储凭据等敏感信息,您应该使用 iOS 下的钥匙串和 Android 下的密钥库。

有一个名为 flutter_secure_storage 的完美库。

使用方法如下:

// Create storage
final storage = new FlutterSecureStorage();

// Store password 
await storage.write(key: "password", value: "my-secret-password");

// Read value 
String myPassword = await storage.read(key: "password");

要使用它,请在终端中为您添加 flutter_secure_storage: 3.2.1+1 pubspec.yaml 和 运行 flutter packages get

这里是包和一个关于如何使用它的更详细的例子: https://pub.dartlang.org/packages/flutter_secure_storage

import 'package:flutter_secure_storage/flutter_secure_storage.dart';
/*  
* Example of a secure store as a Mixin 
* Usage: 

import '../mixins/secure_store_mixin.dart';

MyClass extends StatelessWidget with SecureStoreMixin {

  exampleSet(){
    setSecureStore('jwt', 'jwt-token-data');
  }

  exampleGet(){
     getSecureStore('jwt', (token) { print(token); });
  }
}

*/

class SecureStoreMixin{

  final secureStore = new FlutterSecureStorage();

  void setSecureStore(String key, String data) async {
    await secureStore.write(key: key, value: data);
  }

  void getSecureStore(String key, Function callback) async {
    await secureStore.read(key: key).then(callback);
  }

}

注意:通过添加更多方法进行扩展:

  • 获取全部:Map<String, String> allValues = await secureStore.readAll();
  • 删除:await secureStore.delete(key: key);
  • 全部删除:await secureStore.deleteAll();

评论:我不明白罗宾是如何回答这个问题的。原始发布者需要应用程序具有访问 API 的凭据。使用安全密钥存储不会为应用程序提供任何数据,因此它仍然无法访问 API。如果将文件添加到项目中,则安全密钥存储不会以任何方式保护文件。


2 方法

环境变量:我建议对随环境变化的变量使用环境变量:你可能有2个API_KEYS因为你有生产和测试环境。但是,使用您的应用程序的攻击者仍然可以通过 'man-in-the-middling'-ing 您的请求来窃取它,例如,使用 proxyman.A 攻击者可以嗅探流量或反编译您的应用程序以窃取 API_KEYS 并将它们用于他们自己的项目、漏洞利用或加密货币挖矿。因此,如果您使用环境变量,请确保您的 API 键没有那么强大。一些 API 供应商将允许您限制该密钥的权力。

Backend: 因此,如果 API_KEY 功能强大且不受限制,则根本不应在应用程序上使用它。它应该在您的后端,它代表客户调用外部 APIs。您可以托管服务器来执行此操作,或使用无服务器功能(例如 AWS Lambda、GCP 云功能、Azure 功能、Firebase 云功能等)。


一个例子

这取决于您的威胁模型:您认为您的应用可能受到何种威胁。就我而言,我并不担心有人反编译我的黑客马拉松项目以窃取我免费获得的天气 API_KEY,但我担心某些 github 爬虫或 api供应商找到这个 api_key 并禁用它(这发生在我的朋友身上,她的 Google Cloud Platform 服务帐户凭据)。所以,我正在使用环境变量。