Storing API credentials in a flutter application
For storing sensitive information like credentials you should use the Keychain unter iOS and the Keystore under Android.
There is a perfect library for that called flutter_secure_storage
.
Here's how to use that:
// 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");
To use it add flutter_secure_storage: 3.2.1+1
to you pubspec.yaml
and run flutter packages get
in a terminal.
Here is the package and a more detailled example on how to use it: 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);
}
}
Note: Extend by adding more methods:
- get all:
Map<String, String> allValues = await secureStore.readAll();
- delete:
await secureStore.delete(key: key);
- delete all:
await secureStore.deleteAll();
Comment: I dont see how Robin actually answers the question. The original poster needs the application to have credentials to access an API. Using secure key storage does not give the application any data so it still can't access the API. If you add the file in your project, then secure key storage does not secure the file in any way.
2 approaches
Environment variables: I suggest using environment variables for variables that change depending on the environment: you might have 2 API_KEYS because you have a production and testing environment. However, attackers with your app can still steal this by just 'man-in-the-middling'-ing your requests, for example, using proxyman.A ttackers can sniff traffic or decompile your application to steal API_KEYS and use them in their own projects, exploits or cryptomining. Therefore, if you’re using environment variables, ensure your API keys are not that powerful. Some API providers will allow you to limit the power of that key.
Backend: So, if the API_KEY is powerful and unrestricted, then it should not be used on the application at all. It should be in your backend, which calls external APIs on behalf of clients. You could host a server to do this, or use serverless functions (e.g. AWS Lambda, GCP cloud functions, Azure functions, Firebase cloud functions, and lots more).
An example
It depends on your threat model: what kind of threats you think is possible against your app. In my case, I'm not that bothered about someone decompiling my hackathon project to steal a weather API_KEY that I got for free, but I am afraid that some github crawlers or the api provider finding this api_key and disabling it (This happened to my friend with her Google Cloud Platform service account credentials). So, I am using environment variables.