Query Elastic App Search with flutter using public api key - flutter

I am developing a Flutter mobile and web app to query data from Elasticsearch.
The Elastic App Search provides me a public search key which I would like my Flutter app to use to get data from my index.
All the examples e.g. https://pub.dev/packages/elastic_client do authenticate with basic auth and user/pass.
Are there any approaches or existing libraries which I may use with Flutter?
Currently I am stuck at the very beginning.
I successfully connected the "Search with Elastic App Search" AddOn in Firebase to update my Elastic documents when a document in my Cloud Firestore changes.
In my Flutter app I would like to only query the Elasic index. There is no need for insert, update nor delete.
Before, I used Algolia https://pub.dev/packages/algolia where I could set up e.g.
static const Algolia algolia = Algolia.init(
applicationId: '<my-application-id>',
apiKey: '<my-api-key>',
);
Now I am looking for something similar to connect to my Elastic App Search.
Do I have a general misunderstanding or did I miss anything in my plan?

There's a way to utilize public key with elastic_client, simply place api key as the authorization parameter:
Client.HttpTransport(url: 'https://ES_ENDPOINT:9243/', authorization: "ApiKey <BASE64_ENCODED_VALUE>");
The trick is to add "ApiKey" in front of the hashed/encoded value. Encoded value contains <id>:<api_key>, values generated via POST /_security/api_key (Create ES API key).

Related

Flutter: Error when I add a product in firestore [duplicate]

I was trying to use the GCP filestore, following the simple quick example in the product website and get an error: "google.api_core.exceptions.FailedPrecondition: 400 The Cloud Firestore API is not available for Cloud Datastore projects."
I did use the datastore before in the same project, I then disabled the datastore api in the project and try out the example, still get the same error any one can suggest what to do other than creating a new project ?
If you have an empty Cloud Datastore database and you never executed a write to the database, you can upgrade to Cloud Firestore in Datastore mode or Native mode, by clicking the ‘’UPGRADE TO FIRESTORE’ button on the ‘Datastore/Entities’ page.
If you do not receive the option, then your database instance will be automatically upgraded at a future date(link). If you upgrade from Cloud Datastore to Cloud Firestore in Datastore mode or from Datastore mode to Native mode, you cannot undo the operation.
Here is the link to the Doc: https://cloud.google.com/datastore/docs/upgrade-to-firestore
I had The Cloud Firestore API is not available for Datastore Mode projects with an empty Firestore.
I've solved the error with the steps:
Open Firestore in your web browser.
Create at least one collection.
Sadly, Google error messages are useless, as you see by this example.
I had the same problem, the solution was to comment the line .setProjectId(projectId).
this example is for a native firestore instance, located in another GCP project
GoogleCredentials credentials = GoogleCredentials.fromStream(new ClassPathResource("/test-firebase.json").getInputStream());
FirebaseOptions options = new FirebaseOptions.Builder()
.setCredentials(credentials)
//.setProjectId(projectId)
.setDatabaseUrl("https://document-db.firebaseio.com/")
.build();
if (FirebaseApp.getApps().isEmpty()) {
FirebaseApp.initializeApp(options);
}
Firestore db = FirestoreClient.getFirestore();
DocumentReference docRef = db.collection("document-db").document("alovelace");
// Add document data with id "alovelace" using a hashmap
Map<String, Object> data = new HashMap<>();
data.put("first", "Ada");
data.put("last", "Lovelace");
data.put("born", 1815);
// asynchronously write data
ApiFuture<WriteResult> result = docRef.set(data);

What is the best way to store api keys on flutter?

I want to store an api key on my flutter app. I was thinking about requesting the api key from the server on user registration, and then save it with flutter_secure_storage.
Is that a good way to get and store api keys?
As seen here.
The most secure way to keep your keys as secret, is to NEVER put them in your app because someone could decompile your app and get them, but if you really want to store them in the app the most recommended approach I have found is using text assets. In Flutter you just need to load your file containing your secret keys as if your were loading any other asset.
Create a file called secrets.json that will keep our secret API keys. And store it in the root directory of our project. Remember not to commit your secrets.json file to version control.
write an entry in pubspec.yaml pointing to our secret file.
assets:
- secrets.json
define the class that will keep our keys, let’s say it’s called Secret
class Secret {
final String apiKey; Secret({this.apiKey = ""});
factory Secret.fromJson(Map<String, dynamic> jsonMap) {
return new Secret(apiKey: jsonMap["api_key"]);
}
}
Then a SecretLoader
import 'dart:async' show Future;
import 'dart:convert' show json;
import 'package:flutter/services.dart' show rootBundle;class SecretLoader {
final String secretPath;
SecretLoader({this.secretPath}); Future<Secret> load() {
return rootBundle.loadStructuredData<Secret>(this.secretPath,
(jsonStr) async {
final secret = Secret.fromJson(json.decode(jsonStr));
return secret;
});
}
}
After that, you can just use your SecretLoader like this:
Future<Secret> secret = SecretLoader(secretPath: "secrets.json").load();
Definitely yes from me! It is a best way to store data in secure storage
flutter_secure_storage: ^4.2.0
I'm running into this same question on best practices for API keys in Flutter. I've read many responses across multiple stack posts. It seems that no matter what we do, someone dedicated enough will get the API key so we must turn our attention to limiting the actions of the API.
I'm using Algolia in my project so I'm going to use this service as an example. This service gives you multiple API keys. One of them is for "search only" and another is the ADMIN API key.
The Search Only API key comes with parameters that you can set to prevent API abuse and additionally only allows reads, and does not allow writes or deletes. The Search only API key is what we will expose in our front end and NEVER expose our Admin API key.
I will still follow best practices on utilizing gitIgnore and doing my best to prevent API compromise but from what I've gathered it seems the most effective method is at the API source. I hope this helps in some way.

Hiding fusion charts license

I have a purchased license at fusion charts. Fusion charts document says here... https://www.fusioncharts.com/dev/upgrading/license-activation that i have to use this function call for applying license...
FusionCharts.options.license({
key: 'KEY_GOES_HERE',
creditLabel: false,
});
if i put my key in that anyone visiting my website can easily take it from view -> source of browser. how do i avoid it ? It is simple HTML website.
You can use either of the followings :
Instead of passing the keys directly in JS code, pass them via the environment, application variables. And add the env file to gitignore
Use Obfuscation for the key and JS code being used for license activation.
You can store the value of the key in your database & and fetch the data value so that the end-user is unable to access it.
If you know the domain/sub-domains where charts will be used, you can restrict the license keys to those domains by sending a request to sales#fusioncharts.com
As far as I know, there is no way to completely hide it from the frontend. The reason for this is that even if the key is hidden in some way when the request is made, the information has to exist and so the key could be found by looking at the request data.
What you wish to protect against determines how you should go about it. If you would just like to hide it from being picked up by webscrapers, then I would imagine encrypting it and then decrypting it before you send would be sufficient.
If you would like to protect against anyone stealing it, then the only way is to have a server act as a proxy. You would make a call to an API which would then use your API key on the backend, away from the prying eyes of users. Your backend API would then just return to the user the response from fusioncharts.

How to pass dynamic values to Apigee with key?

I have a rest application that pulls data from database based on the user choice of City or County via UI.
The city, and county are dynamically passed in as the user is able to choose all 50 states.
The endpoints are like this:
http://localhost:8080/my-api/state/FL/City
http://localhost:8080/my-api/state/FL/County
http://localhost:8080/my-api/state/CA/City
http://localhost:8080/my-api/state/AK/County
etc...etc....
Now I want to secure these endpoints using Apigee along with a key. I have created the proxy and product and able to get json from application with my new Apigee URL:
https://company.api-nonprod.com/my-first-api/state/TX/City?apikey=ldekQ5VqlXFQq7YusetSeqbeidxdo5
So far so good. :)
Now I need to add this EndPoint to the front end configuration file.
My local endpoint worked fine.
http://localhost:8080/my-api/state
How do I add this new Apigee Endpoint and key?
This doesn't work as it keeps appending the parameters to the end of url instead of before the apikey.
https://company.api-nonprod.com/my-first-api/state?apikey=ldekQ5VqlXFQq7YusetSeqbeidxdo5
error url
https://company.api-nonprod.com/my-first-api/state?apikey=ldekQ5VqlXFQq7YusetSeqbeidxdo5/TX/City
After going over the Apigee documentation I made my way to the Develop tab in which I can specify how the APIKey can be referenced.
<VerifyAPIKey name="APIKeyVerifier">
<APIKey ref="request.formparam.x-apikey"/>
</VerifyAPIKey>
<VerifyAPIKey name="APIKeyVerifier">
<APIKey ref="request.header.x-apikey"/>
</VerifyAPIKey>
<VerifyAPIKey name="APIKeyVerifier">
<APIKey ref="request.queryparam.x-apikey"/>
</VerifyAPIKey>
Now I'm stuck in AssignMessage message documentation.
How do I pass dynamic values to Apigee with key?
You have to handle constructing URL in your application.
Try to hit from postman.. have your proxy url and your requestMapping appened with your proxy url.
it should work, or it would have worked by this time ;) , since two months gone :P

Autocomplete testing on Azure Search explorer

I am trying to build and test the auto complete feature on a master item lookup tables using Azure Search (for a ASP MVC application). The search index was done with the suggesterName SG set to ItemDisplayName
I was looking to test it first on Azure portal- so that I could aim to replicate the results via code. This is because the results I am getting in code are quite unexpected
As I type the substring the itemDislayName, the expectation was that upto 5 selected names will be displayed
On the portal, I tried a query string of
search=str&suggesterName=SG
with the base request URL containing the index, api version and sugestorName-but I don't get results of items containing 'str' and with the fuzziness as below
Could you please guide around
[1] how I can get suggestor output in azure portal-search explorer
[2] can I control fuzziness using queryType and ~1,~2
I was referring to these 3 links
1) https://learn.microsoft.com/en-us/rest/api/searchservice/suggestions
and
2) https://channel9.msdn.com/Shows/Azure-Friday/Azure-Search-103-Azure-Search-Suggestions-with-Liam-Cavanagh
3) gunnarpeipman.com/2016/07/azure-search-suggesters/
Azure Search Portal doesn't support the Suggestion API yet. You will need to use an HTTP client like Fiddler or Postman.
Make sure you use the right URL for you Suggest requests:
https://[service name].search.windows.net/indexes/[index name]/docs/suggest
Please use our User Voice page to vote for adding the Suggest API to the Portal: https://feedback.azure.com/forums/263029-azure-search