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

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);
}

Related

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

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
})

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.

How to remove Authorization header on redirect on any Flutter/Dart http client

I'm currently working on a project which like a lot of other projects works with s3 storage. In this case the storage is linked via the back-end.
The situation is like this, I can get the 'attachment' via an URL, lets say example.com/api/attachments/{uuid}. If the user is authorized (via the header Authorization) it should return a 302 statuscode and redirect to the s3 url. The problem is that after the redirect the Authorization header persists and the http client return a 400 response and it's because of the persisting Authorization header. Is there any way I can remove the Authorization header after redirect without catching the first request and firing a new one?
My http client code currently looks like this:
#override
Future get({
String url,
Map<String, dynamic> data,
Map<String, String> parameters,
}) async {
await _refreshClient();
try {
final response = await dio.get(
url,
data: json.encode(data),
queryParameters: parameters,
);
return response.data;
} on DioError catch (e) {
throw ServerException(
statusCode: e.response.statusCode,
message: e.response.statusMessage,
);
}
}
Future<void> _refreshClient() async {
final token = await auth.token;
dio.options.baseUrl = config.baseUrl;
dio.options.headers.addAll({
'Authorization': 'Bearer $token',
'Accept': 'application/json',
});
dio.options.contentType = 'application/json';
}
Good news! This has been fixed recently with Dart 2.16 / Flutter v2.10!
Related bugs in dart issue tracker:
https://github.com/dart-lang/sdk/issues/47246
https://github.com/dart-lang/sdk/issues/45410
Official announcement:
https://medium.com/dartlang/dart-2-16-improved-tooling-and-platform-handling-dd87abd6bad1
TLDR: upgrade to Flutter v2.10!
Looking at the Dio docs, it seems like this is intentional behaviour.
All headers added to the request will be added to the redirection request(s). However, any body send with the request will not be part of the redirection request(s).
https://api.flutter.dev/flutter/dart-io/HttpClientRequest/followRedirects.html
However, I understand (and agree!) that this is generally undesirable behaviour. My solution is to manually follow the redirects myself, which is not very nice but works in a pinch.
Response<String> response;
try {
response = await dio.get(
url,
options: Options(
// Your headers here, which might be your auth headers
headers: ...,
// This is the key - avoid following redirects automatically and handle it ourselves
followRedirects: false,
),
);
} on DioError catch (e) {
final initialResponse = e.response;
// You can modify this to understand other kinds of redirects like 301 or 307
if (initialResponse != null && initialResponse.statusCode == 302) {
response = await dio.get(
initialResponse.headers.value("location")!, // We must get a location header if we got a redirect
),
);
} else {
// Rethrow here in all other cases
throw e;
}
}

How to send a token in a request in flutter?

I am making a flutter application, and i have written a server in django. When i send a token to my server for authentication then my server sends me an error of undefined token. Without token all requests works fine, but when i add a token then it gives me an error
{detail: Authentication credentials were not provided.}
But When i add token in modheader, my server works fine
Authorization: Token bff0e7675d6d80bd692f1be811da63e4182e4a5f
This is my flutter code
const url = 'MY_API_URL';
var authorization = 'Token bff0e7675d6d80bd692f1be811da63e4182e4a5f';
final response = await http.get(
url,
headers: {
'Content-Type': 'application/json',
'Authorization': authorization,
}
);
final responseData = json.decode(response.body);
print('responseData');
print(responseData);
try this:
Map<String, String> headers = {
HttpHeaders.contentTypeHeader: 'application/json',
HttpHeaders.acceptHeader: 'application/json',
HttpHeaders.authorizationHeader: 'Token bff0e7675d6d80bd692f1be811da63e4182e4a5f'
};
& use them in request
final response = await http.get(
url,
headers: headers,
);
As I don't know to work on your API so I can't tell you the exact answer.
Check that, Is your backend taking authorization by header or body or
I'll suggest you first make authorization by tools like postman then
if that succeeds then try to implement that in your app.