//here is my code
import 'package:shelf/shelf.dart';
import 'package:shelf/shelf_io.dart' as shelf_io;
void main() async {
var handler =
const Pipeline().addMiddleware(logRequests()).addHandler(_echoRequest);
var server = await shelf_io.serve(handler, 'localhost', 8080);
// Enable content compression
server.autoCompress = true;
print('Serving at http://${server.address.host}:${server.port}');
}
Response _echoRequest(Request request) =>
Response.ok('Request for "${request.url}"');
I am trying to request a token to the Here API with Rest service java in order to obtain OAuth 2.0 Token Credentials. I am blocked in the request level and constantly having the same error but according to the documentation I don't do anything wrong.
Here is the necessary code in REST Java to make the request.
The below code i tried.
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.List;
import javax.crypto.Mac;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import org.apache.commons.codec.binary.Base64;
import org.apache.http.HttpEntity;
import org.apache.http.HttpHeaders;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.utils.URLEncodedUtils;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicNameValuePair;
public class here {
private static final String HMAC_SHA256 = "HmacSHA256";
private static final String ENC = "UTF-8";
private static Base64 base64 = new Base64();
private static String key = "MyKeyID"; // here.access.key.id from credential file
private static String secret = "MySecretKey" //here.access.key.secret
public static void main(String[] args) {
HttpClient httpClient = new DefaultHttpClient();
long value = (System.currentTimeMillis() / 1000);
int unique = (int) (Math.random() * 100000000);
// These params should ordered in key
List<NameValuePair> qparams = new ArrayList<NameValuePair>();
qparams.add(new BasicNameValuePair("grant_type", "client_credentials"));
qparams.add(new BasicNameValuePair("oauth_consumer_key", "MY_KEY_ID"));
qparams.add(new BasicNameValuePair("oauth_nonce", ""
+ unique));
qparams.add(new BasicNameValuePair("oauth_signature_method",
"HMAC-SHA256"));
qparams.add(new BasicNameValuePair("oauth_timestamp", ""
+ value));
qparams.add(new BasicNameValuePair("oauth_version", "1.0"));
System.err.println("query param->>>");
// creating authentication signature
String signature = getSignature(URLEncoder.encode(
"https://account.api.here.com/oauth2/token", ENC),
URLEncoder.encode(URLEncodedUtils.format(qparams, ENC), ENC));
// comibining the params
String authHeader = "OAuth oauth_consumer_key=MY_KEY,"
+"oauth_nonce="+unique+","
+"oauth_signature="+signature+","
+"oauth_signature_method=HMAC-SHA256,"
+"oauth_timestamp="+value+","
+"oauth_version=1.0";
HttpPost httpPost = new HttpPost("https://account.api.here.com/oauth2/token");
httpPost.addHeader("Content-Type", "application/x-www-form-urlencoded");
httpPost.setHeader(HttpHeaders.AUTHORIZATION, authHeader);
String grant_type = "client_credentials";
StringEntity input = new StringEntity("grant_type=" + grant_type);
httpPost.setEntity(input);
// output the response content.
System.out.println("Token and Token Secrect:");
HttpResponse response = httpClient.execute(httpPost);
HttpEntity entity = response.getEntity();
if (entity != null) {
InputStream instream = entity.getContent();
int len;
byte[] tmp = new byte[2048];
try {
while ((len = instream.read(tmp)) != -1) {
System.out.println(new String(tmp, 0, len, ENC));
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
private static String getSignature(String url, String params) throws UnsupportedEncodingException, NoSuchAlgorithmException, InvalidKeyException {
StringBuilder base = new StringBuilder();
base.append("POST&");
base.append(url);
base.append("&");
base.append(params);
System.out.println("Stirng for oauth_signature generation:" + base);
// yea, don't ask me why, it is needed to append a "&" to the end of
// secret key.
byte[] keyBytes = (secret + "&").getBytes(ENC);
SecretKey key = new SecretKeySpec(keyBytes, HMAC_SHA256);
Mac mac = Mac.getInstance(HMAC_SHA256);
mac.init(key);
// encode it, base64 it, change it to string and return.
return new String(base64.encode(mac.doFinal(base.toString().getBytes(
ENC))), ENC).trim();
}}
And this is the error that I keep getting :
{"errorId":"ERROR-27b88f02-5d76-40ea-81d5-de6e70cf8464","httpStatus":401,"errorCode":401205,"message":"Unsupported signature method in the header. Require HMAC-SHA256","error":"invalid_request","error_description":"errorCode: '401205'. Unsupported signature method in the header. Require HMAC-SHA256"}
According to the documentation, https://developer.here.com/documentation/authentication/dev_guide/topics/using-aaa-javasdk-or-3rd-party-libraries.html
I develop the code based on the above api documentation but iam not getting the result.
Does anyone know how to fix this issue?
I tried this code
HttpClient httpClient = HttpClientBuilder.create().build();
String headers = "grant_type=client_credentials"+"&oauth_consumer_key=mykey"+"&oauth_nonce=uniquevalue"+"&oauth_signature_method=HMAC-SHA256"+"&oauth_timestamp=timestamp"+"&oauth_version=1.0";
String combine = "POST"+"\n&"+URLEncoder.encode("https://account.api.here.com/oauth2/token", StandardCharsets.UTF_8.toString())+"\n&"+URLEncoder.encode(headers, StandardCharsets.UTF_8.toString());
Mac sha256_HMAC = Mac.getInstance("HmacSHA256");
SecretKeySpec secret_key = new SecretKeySpec(("mysecretkey &").getBytes(), "HmacSHA256");
sha256_HMAC.init(secret_key);
String signature = Base64.encodeBase64String(sha256_HMAC.doFinal(combine.getBytes()));
String authHeader = "OAuth "
+ "oauth_consumer_key=\"X1E2a0ElfkaHx7aezqN5Hg-1234\","
+"oauth_nonce=\"uniquevalue\","
+"oauth_signature=\""+signature+"\","
+"oauth_signature_method=\"HMAC-SHA256\","
+"oauth_timestamp=\"timestamp\","
+"oauth_version=\"1.0\"";
HttpPost httpPost = new HttpPost("https://account.api.here.com/oauth2/token");
httpPost.addHeader("Content-Type", "application/x-www-form-urlencoded");
httpPost.addHeader("Host", "account.api.here.com");
httpPost.setHeader(HttpHeaders.AUTHORIZATION, authHeader);
StringEntity input = new StringEntity("grant_type=" + "client_credentials");
httpPost.setEntity(input);
HttpResponse response = httpClient.execute(httpPost);
HttpEntity entity = response.getEntity();
Its showing one more error like errorCode: '401202'. Invalid Client Authorization header, expecting signed request format. Please give some suggestion how to request a toke ?
Can you try to modify your code as-
// creating authentication signature
String signature = getSignature(URLEncoder.encode(
"https://account.api.here.com/oauth2/token", ENC),
URLEncoder.encode(URLEncodedUtils.format(qparams, ENC), ENC));
// comibining the params
String authHeader = "OAuth oauth_consumer_key=MY_KEY,"
+"oauth_nonce="+unique+","
+"oauth_signature="+URLEncoder.encode(signature,"UTF-8")+","
+"oauth_signature_method=HMAC-SHA256,"
+"oauth_timestamp="+value+","
+"oauth_version=1.0";
I tried your solution and got the same error. There is some problem with the generated signature. I found this official Here Java SDK, which has classes to generate signature and Authorization Header.
https://github.com/heremaps/here-aaa-java-sdk/blob/acf6c7a982070f0b311c1741ce4887938b60df5b/here-oauth-client/src/main/java/com/here/account/auth/SignatureCalculator.java#L101
Hope this helps !
I am trying to upload image from client (flutter) to server (Aqueduct.io) using MultipartRequest.
It's working, but currently file names are assigned the current time, how can I pass the filename from a client and parse it on a server side?
Client code:
final String imageName = nameController.text.replaceAll(" ", "");
var postUri = Uri.parse("http://***:8888/media");
var request = new http.MultipartRequest("POST", postUri);
request.files.add(new http.MultipartFile.fromBytes('file', image,
filename: imageName, contentType: MediaType('image', 'jpeg')));
request.send().then((response) {
if (response.statusCode == 200) print("Uploaded!");
});
}
Server code:
import 'dart:async';
import 'dart:io';
import 'package:aqueduct/aqueduct.dart';
import 'package:mime/mime.dart';
import 'package:http_server/http_server.dart';
class MediaController extends ResourceController {
MediaController() {
acceptedContentTypes = [ContentType("multipart", "form-data")];
}
#Operation.post()
Future<Response> postMultipartForm() async {
final transformer = MimeMultipartTransformer(
request.raw.headers.contentType.parameters["boundary"]);
final bodyStream =
Stream.fromIterable([await request.body.decode<List<int>>()]);
final parts = await transformer.bind(bodyStream).toList();
for (var part in parts) {
final HttpMultipartFormData multipart = HttpMultipartFormData.parse(part);
final content = multipart.cast<List<int>>();
final filePath =
"public/" + DateTime.now().millisecondsSinceEpoch.toString() + ".jpg"; // <---current filename implementation
final IOSink sink = File(filePath).openWrite();
await for (List<int> item in content) {
sink.add(item);
}
await sink.flush();
await sink.close();
}
return Response.ok({});
}
}
Okay, I have the asnwer
import 'dart:async';
import 'dart:io';
import 'package:aqueduct/aqueduct.dart';
import 'package:mime/mime.dart';
import 'package:http_server/http_server.dart';
class MediaController extends ResourceController {
MediaController() {
acceptedContentTypes = [ContentType("multipart", "form-data")];
}
#Operation.post()
Future<Response> postMultipartForm() async {
final transformer = MimeMultipartTransformer(
request.raw.headers.contentType.parameters["boundary"]);
final bodyStream =
Stream.fromIterable([await request.body.decode<List<int>>()]);
final parts = await transformer.bind(bodyStream).toList();
for (var part in parts) {
final HttpMultipartFormData multipart = HttpMultipartFormData.parse(part);
List<String> tokens = part.headers['content-disposition'].split(";");
String filename;
for (var i = 0; i < tokens.length; i++) {
if (tokens[i].contains('filename')) {
filename = tokens[i]
.substring(tokens[i].indexOf("=") + 2, tokens[i].length - 1);
}
}
print('file $filename.jpg uploaded');
final content = multipart.cast<List<int>>();
final filePath =
// "public/" + DateTime.now().millisecondsSinceEpoch.toString() + ".jpg";
'public/$filename.jpg';
final IOSink sink = File(filePath).openWrite();
await for (List<int> item in content) {
sink.add(item);
}
await sink.flush();
await sink.close();
}
return Response.ok({});
}
}
import 'package:http/http.dart' as http;
main() {
String esearch = "http://eutils.ncbi.nlm.nih.gov/entrez/eutils/esearch.fcgi?db=nucleotide&term=Paenibacillus";
var uidList = [];
http.get(esearch).then((response) {
var pattern = new RegExp(r"<Id>(.*?)</Id>");
var hits = pattern.allMatches(response.body);
hits.forEach((hit) {
print("whole match: " + hit[0] + " first match " + hit[1]);
uidList.add(hit[1]);
});
});
print(uidList.length); // empty, because main thread is faster than query
}
Hello everyone,
I'm playing around with Dart since one day to figure out, whether it's suitable for my needs. In the code I have attached, I want to access the result of the body outside of the http query block. This isn't possible. In another question here, someone writes this is because of Darts async concept.
Is there a way to get access to from outside. This is import because I have to trigger several htttp requests with the resulting data and don't wont to nest them all within the http block.
Or any other suggestions?
Thank you very much.
This doesn't work this way because an async call (http.get()) is scheduled for later execution and than execution proceeds with the next line. Your print is executed before http.get() even started to connect. You need to chain all successive calls with then.
If you have a recent Dart version you can use async/await which makes using async calls easier.
import 'package:http/http.dart' as http;
main() {
String esearch = "http://eutils.ncbi.nlm.nih.gov/entrez/eutils/esearch.fcgi?db=nucleotide&term=Paenibacillus";
var uidList = [];
return http.get(esearch).then((response) {
var pattern = new RegExp(r"<Id>(.*?)</Id>");
var hits = pattern.allMatches(response.body);
hits.forEach((hit) {
print("whole match: " + hit[0] + " first match " + hit[1]);
uidList.add(hit[1]);
});
return uidList;
}).then((uidList) {
print(uidList.length);
});
}
async/await
import 'package:http/http.dart' as http;
main() async {
String esearch = "http://eutils.ncbi.nlm.nih.gov/entrez/eutils/esearch.fcgi?db=nucleotide&term=Paenibacillus";
var uidList = [];
var response = await http.get(esearch);
var pattern = new RegExp(r"<Id>(.*?)</Id>");
var hits = pattern.allMatches(response.body);
hits.forEach((hit) {
print("whole match: " + hit[0] + " first match " + hit[1]);
uidList.add(hit[1]);
});
print(uidList.length);
}
I'm in struggle with downloading a picture and then showing it on a page. Printed base64-encoded string looks wrong; it's not identical with e.g. http://www.freeformatter.com/base64-encoder.html result.
This is my code:
HttpRequest.request(_url).then((HttpRequest response) {
String contentType = response.getResponseHeader('Content-Type');
if (_supportedContentType(contentType)) {
List bytes = new Utf8Encoder().convert(response.responseText);
String header = 'data:$contentType;base64,';
String base64 = CryptoUtils.bytesToBase64(bytes);
String image = "${header}${base64}";
me.avatar = image;
print(image);
}
}
When you set the responseType you get binary data
import 'dart:html' show HttpRequest;
import 'dart:convert' show base64;
import 'dart:typed_data' show Uint8List, ByteBuffer;
main() {
HttpRequest
.request("Zacharie_Noterman_-_Monkey_business.jpg",
responseType: "arraybuffer")
.then((HttpRequest response) {
String contentType = response.getResponseHeader('Content-Type');
var list = new Uint8List.view((response.response as ByteBuffer));
String header = 'data:$contentType;base64,';
String base64 = base64.encode(list);
String image = "${header}${base64}";
// me.avatar = image;
print(image);
//}
});
}
result:
data:image/png;base64,/9j/4AAQSkZJRgABAQEAYABgAAD....