When making a request to the Vision API Product Search an error occurs "message": "The request is missing a valid API key." - flutter

When I register a service account for the Vision API Product Search there's a json file downloaded into my desktop that has the private key. However, when making a request into this api there's no place to send that JSON. I'll show you the documentation and my code.
I didn't understand also what is the curl request and how to send it using the http post request.
And This is my code:
Future<void> uploadProductSet() async {
var projectId = 'estoOne';
var locationId = 'europe-west1';
var url = 'https://vision.googleapis.com/v1/projects/$projectId/locations/$locationId/productSets';
final responseOne = await http
.post(Uri.parse(url),
body: json.encode({
'displayName': 'Product-Set-One',
}))
.catchError((error) {
throw error;
});
print(resoinseOne.body);
}

You have to send your access token with the Authorization header.
The API seems to use the Bearer authentication method.
So set the following header in your http request: Bearer $authToken
You should get the auth-token from the credentials file you've downloaded
So your code should look something like this: (untested)
await http.post(Uri.parse(url),
headers: { 'Authorization': 'Bearer $authToken' },
body: json.encode({
'displayName': 'Product-Set-One',
})).catchError((error) {
throw error
})

Related

CORS error: Request header field authorization is not allowed by Access-Control-Allow-Headers in preflight response

I'm trying to fetch an image resource that's part of a conversation message.
I've tried both FETCH as well as using AXIOS but I'm getting the same error message.
Here's an example of my FETCH request
const token = `${accountSid}:${authToken}`;
const encodedToken = Buffer.from(token).toString('base64');
let response = await fetch('https://mcs.us1.twilio.com/v1/Services/<SERVICE_SID>/Media/<MEDIA_SID>',
{
method:'GET',
headers: {
'Authorization': `Basic ${encodedToken}`,
}
});
let data = await response.json();
console.log(data);
And here's what Axios looked like
let config = {
method: 'get',
crossdomain: true,
url: 'https://mcs.us1.twilio.com/v1/Services/<SERVICE_SID>/Media/<MEDIA_SID>',
headers: {
'Authorization': `Basic ${encodedToken}`,
},
};
try {
const media = await axios(config);
console.dir(media);
} catch(err) {
console.error(err);
}
Both ways are NOT working.
After looking into it more, I found out that Chrome makes a pre-flight request and as part of that requests the allowed headers from the server.
The response that came back was this
as you can see, in the "Response Headers" I don't see the Access-Control-Allow-Headers which should have been set to Authorization
What am I missing here?
I have made sure that my id/password as well as the URL i'm using are fine. In fact, I've ran this request through POSTMAN on my local machine and that returned the results just fine. The issue is ONLY happening when I do it in my code and run it in the browser.
I figured it out.
I don't have to make an http call to get the URL. It can be retrieved by simply
media.getContentTemporaryUrl();

Stripe Metadata submission invalid object

I am implementing Stripe payments, but am unable to submit metadata as a query param as per the documentation, it seems as though it wants iterable stringified key-value pairs which I have tried to achieve with the below with no luck.
Question: How can I pass metadata to Stripe using Dart and the HTTP library?
class StripeServices {
static var client = http.Client();
static var stripeTestKey =
'privatesecretkeyfromstripe';
static Future<void> createStripeCustomer() async {
Map<String, String> metadata = {'uuid': '123456'};
Uri uri = Uri(
scheme: 'https',
host: 'api.stripe.com',
path: '/v1/customers',
queryParameters: {
'description': 'Test Customer',
'metadata': metadata.entries.toList().toString()
});
var response = await client.post(
uri,
headers: {
'Authorization': 'Bearer ' + stripeTestKey,
},
);
print(response.body);
}
The error I am getting back from the endpoint is
> flutter: { "error": {
> "message": "Invalid object",
> "param": "metadata",
> "type": "invalid_request_error" } }
calling Stripe API requires a secret API key, and you shouldn't store and use the API key in your frontend application because it's not safe.
Instead you should make the API call from your backend where the API key can be securely stored.

Works via Postman but not in Flutter: API call with GCS pre-signed URL

I'm trying to upload a video file to GCS using a pre-signed url. I've managed to create the url via Google but now I am facing a problem using it.
Upload works in Postman, got response 200.
postman body, postman params
Code copied from Postman results in 403 Forbidden (SignatureDoesNotMatch):
Future<http.StreamedResponse> uploadVideo(
{required String uploadURL, required String filePath}) async {
var headers = {'Content-Type': 'application/octet-stream'};
var request = http.MultipartRequest('PUT', Uri.parse(uploadURL));
request.files.add(await http.MultipartFile.fromPath('file', filePath));
request.headers.addAll(headers);
http.StreamedResponse response = await request.send();
if (response.statusCode == 200) {
print(await response.stream.bytesToString());
} else {
print(response.reasonPhrase);
}
return response;
}
This is the error I am getting from Google:
<?xml version='1.0' encoding='UTF-8'?><Error><Code>SignatureDoesNotMatch</Code><Message>The request signature we calculated does not match the signature you provided. Check your Google secret key and signing method.</Message><StringToSign>GOOG4-RSA-SHA256
20210803T082850Z
20210803/auto/storage/goog4_request
6d513846a3db49f949b0d2eea8f04b90f918b3b94588c3ed55ed3620b7d7e1f6</StringToSign><CanonicalRequest>PUT
/phonedo-interviews/app-test/007/2.mp4
X-Goog-Algorithm=GOOG4-RSA-SHA256&X-Goog-Credential=interviews%40interviews-317011.iam.gserviceaccount.com%2F20210803%2Fauto%2Fstorage%2Fgoog4_request&X-Goog-Date=20210803T082850Z&X-Goog-Expires=900&X-Goog-SignedHeaders=content-type%3Bhost
content-type:multipart/form-data; boundary=dart-http-boundary-6w1yq6BQN3EkGBrhHZnwidOXZsBecsgSwTT3nBjB9vQCToHt0cg
host:storage.googleapis.com
content-type;host
UNSIGNED-PAYLOAD</CanonicalRequest></Error>
Note: I needed Content-Type to be application/octet-stream so I disabled that header in Postman's automatic headers and added Content-Type manually. When I didn't do that I also got 403.
The solution was to send the file in binary.
Here is the working code:
Future<http.Response> uploadVideo(
{required String uploadURL, required String filePath}) async {
var response = await http.put(
Uri.parse(uploadURL),
headers: {'content-type': 'application/octet-stream'},
body: File(filePath).readAsBytesSync(),
);
In your Postman headers, a Token is given to GCS (first line). Given that you need authorization, Postman probably has this Token saved somewhere application-wise.
In this flutter code, the headers you're giving do not include an Auth token and therefore you're receiving a 403 error.

Angular7 Consume Mailchimp RESTFUL API

I'm trying to make HTTP POST request to consume Mailchimp API (From Angular7 code)
but i'm getting this response:
Access to XMLHttpRequest at 'https://us12.api.mailchimp.com/3.0/lists/ddddddd/members' from origin 'http://localhost:4200' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.
From REST client i'm able to make insert in Mailchimp without having this CROS issue
export class MyService {
constructor(public httpRequestsService: HttpRequestsService) { }
private async getHttpHeader() {
const rheaders = new HttpHeaders({
'Content-Type': 'application/json' ,
'Access-Control-Allow-Origin': '*',
'Access-Control-Allow-Methods': 'POST, GET, OPTIONS',
'Access-Control-Allow-Headers':'X-Requested-With',
'Authorization': 'apikey ' + MailchimpSettings.API_KEY
});
return { headers: rheaders };
}
public async AddNewMember(email: string, language = 'en', status = , mergeFields?: any) {
var url = MailchimpSettings.URL;
var body = {
"email_address": email,
"status": MailchimpSettings.SUBSCRIBED_STATUS,
"language": language
};
var httpOptions = await this.getHttpHeader();
var _body = JSON.stringify(body);
var result = await this.post(url, _body, httpOptions);
}
public async post(url: string, body: string | {} = {}, requestHeaders?: any): Promise<Response> {
return this.http.post(url, body, requestHeaders).toPromise()
.then((res: any) => {
return res;
})
.catch((err) => {
return this.handleErrorPromise(err);
});
}
}
Anyone who can help me with right HTTP headers (or any required change) to reproduce exactly REST client behavior and be able to make a successful POST.
Thanks for your help
Unfortunately, the answer is you can't. Mailchimp does not support CORS because that would require passing API credentials, and that is not secure.
The option is to make requests from another server like you mentioned from the REST client or make a custom signup form that will use more restricted API call.
Or use jsonp request for mailchimp form clients.
See this

Node Js Restapi - Calling Post Method in Flutter Doesn't Work

I have local api and jwt by node js i want to send my username and password from flutter and send it to node js to give me this token and later i will save it in local storage but when i tell flutter post to the api doesn't post
my code :
You can use http method here like below Future example
Future postContact(access_token,name,email,phone,message) async {
String apiUrl = '$_apiUrl/user/contact-us';
http.Response response = await http.post(apiUrl,headers: {
"Accept": "application/json",
"Accesstoken": "Bearer $access_token"
}, body: {'name':'$name','email':'$email','phone':'$phone','message':'$message'});
print("Result: ${response.body}");
return json.decode(response.body);
}