4.0.29
You need a secure authentication method for the published API to ensure data security.
FineDataLink supports AK/SK-based digest and signature authentication for APIs, which prevents the authentication information and the request from being intercepted and tampered with during transmission, ensuring authentication security.
The API released by FineDataLink uses HMAC-SHA256 to calculate the signature, and the signature verification logic is:
Request initiator (calculate the signature and attach it to the request) ---> Request recipient (calculate the signature according to the request parameters and verify the signature)
You have published the API, bound the API to an application, and set App Authentication Method to Digest Signature.
POST Request with Content-Type application/json
Create a Java file according to the following sample code:
package kk;import javax.crypto.Mac;import javax.crypto.spec.SecretKeySpec;import java.math.BigInteger;import java.nio.charset.StandardCharsets;import java.security.MessageDigest;import java.util.Base64;import java.util.UUID;public class k { public static void main(String[] args) { //Change it to the corresponding AppSecret. String secretKey = "1bbe91b1-a39c-4742-9694-e126bcf9a3bd"; //Fill in the request method in all caps. String httpMethod = "POST"; //For POST requests, specify the contentType. For GET requests, use an empty string here. String contentType = "application/json"; //Fill in the API path. For GET requests, include the parameters, for example, xxx/xxx?a=1. String pathAndParameters = "a5ce6bb4-467b-46f2-8878-2132635973bb/87"; //Fill in the content of the body request. String data = "{\"paging\":{\"pageSize\":10,\"pageNum\":1},\"params\":[]}"; //The nonce is generated automatically. String nonce = String.valueOf(UUID.randomUUID()); //The timestamp is generated automatically. String timestamp = String.valueOf(System.currentTimeMillis()); //Fill in the string to be signed. String stringToSign = httpMethod +"\n"+ nonce +"\n"+ timestamp +"\n"+ pathAndParameters +"\n"+ contentType +"\n"+ md5(data); //Fill in the signature. String signature = hmacSHA256(secretKey,stringToSign); //Input the complete authorization. System.out.println("Authorization:\n"+"HMAC-SHA256 Signature="+signature+",Nonce="+nonce+",Timestamp="+timestamp); } /** * Create a Base64-encoded signature using the HMAC-SHA256 for the string data. * * @param secretKey Secret key * @param data String to be signed */ public static String hmacSHA256(String secretKey, String data) { try { Mac hmacSha256 = Mac.getInstance("HmacSHA256"); SecretKeySpec secretKeySpec = new SecretKeySpec(secretKey.getBytes(StandardCharsets.UTF_8), "HmacSHA256"); hmacSha256.init(secretKeySpec); byte[] hashBytes = hmacSha256.doFinal(data.getBytes(StandardCharsets.UTF_8)); return Base64.getEncoder().encodeToString(hashBytes); } catch (Exception e) { throw new RuntimeException("HmacSha error", e); } } /** * Calculate the MD5 digest of the string data and perform Base64 encoding on the digest to get the encoded result. * * @param data String to be calculated */ public static String md5(String data) { try { MessageDigest md = MessageDigest.getInstance("MD5"); md.reset(); md.update(data.getBytes(StandardCharsets.UTF_8)); String md5Result = String.format("%032x", new BigInteger(1, md.digest())); return Base64.getEncoder().encodeToString(md5Result.getBytes(StandardCharsets.UTF_8)); } catch (Exception e) { throw new RuntimeException("md5 error", e); } }}
GET Request
package kk;import javax.crypto.Mac;import javax.crypto.spec.SecretKeySpec;import java.math.BigInteger;import java.nio.charset.StandardCharsets;import java.security.MessageDigest;import java.util.Base64;import java.util.UUID;public class k { public static void main(String[] args) { //Change it to the corresponding AppSecret. String secretKey = "a07eefc1-4b29-469a-8cb1-f68e3532d3a2"; //Fill in the request method in all caps. String httpMethod = "GET"; //For POST requests, specify the contentType. For GET requests, use an empty string here. String contentType = ""; //Fill in the API path. For GET requests, include the parameters, for example, xxx/xxx?a=1. String pathAndParameters = "a5ce6bb4-467b-46f2-8878-2132635973bb/dd?pageSize=10&pageNum=1"; //Fill in the content of the body request. String data = ""; //The nonce is generated automatically. String nonce = String.valueOf(UUID.randomUUID()); //The timestamp is generated automatically. String timestamp = String.valueOf(System.currentTimeMillis()); //String to be signed String stringToSign = httpMethod +"\n"+ nonce +"\n"+ timestamp +"\n"+ pathAndParameters +"\n"+ contentType +"\n"+ ("".equals(data)?"":md5(data)); //Fill in the signature String signature = hmacSHA256(secretKey,stringToSign); //Input the complete authorization. System.out.println("Authorization:\n"+"HMAC-SHA256 Signature="+signature+",Nonce="+nonce+",Timestamp="+timestamp); } /** * Create a Base64-encoded signature using the HMAC-SHA256 for the string data. * * @param secretKey Secret key * @param data String to be signed */ public static String hmacSHA256(String secretKey, String data) { try { Mac hmacSha256 = Mac.getInstance("HmacSHA256"); SecretKeySpec secretKeySpec = new SecretKeySpec(secretKey.getBytes(StandardCharsets.UTF_8), "HmacSHA256"); hmacSha256.init(secretKeySpec); byte[] hashBytes = hmacSha256.doFinal(data.getBytes(StandardCharsets.UTF_8)); return Base64.getEncoder().encodeToString(hashBytes); } catch (Exception e) { throw new RuntimeException("HmacSha error", e); } } /** * Calculate the MD5 digest of the string data and perform Base64 encoding on the digest to get the encoded result. * * @param data String to be calculated */ public static String md5(String data) { try { MessageDigest md = MessageDigest.getInstance("MD5"); md.reset(); md.update(data.getBytes(StandardCharsets.UTF_8)); String md5Result = String.format("%032x", new BigInteger(1, md.digest())); return Base64.getEncoder().encodeToString(md5Result.getBytes(StandardCharsets.UTF_8)); } catch (Exception e) { throw new RuntimeException("md5 error", e); } }}
POST Request with Content-Type application/x-www-form-urlencoded
package kk;import javax.crypto.Mac;import javax.crypto.spec.SecretKeySpec;import java.math.BigInteger;import java.nio.charset.StandardCharsets;import java.security.MessageDigest;import java.util.Base64;import java.util.UUID;public class k { public static void main(String[] args) { //Change it to the corresponding AppSecret. String secretKey = "1bbe91b1-a39c-4742-9694-e126bcf9a3bd"; //Fill in the request method in all caps. String httpMethod = "POST"; //For POST requests, specify the contentType. For GET requests, use an empty string here. String contentType = "application/x-www-form-urlencoded"; //Fill in the API path. For GET requests, include the parameters, for example, xxx/xxx?a=1. String pathAndParameters = "a5ce6bb4-467b-46f2-8878-2132635973bb/87"; //Fill in the content of the body request. The key-value pairs in the body also need to be encoded. String data = "a=1&b=%E6%8C%AA%E5%A8%81"; //The nonce is generated automatically. String nonce = String.valueOf(UUID.randomUUID()); //The timestamp is generated automatically. String timestamp = String.valueOf(System.currentTimeMillis()); //Fill in the string to be signed. String stringToSign = httpMethod +"\n"+ nonce +"\n"+ timestamp +"\n"+ pathAndParameters +"\n"+ contentType +"\n"+ md5(data); //Signature String signature = hmacSHA256(secretKey,stringToSign); //Input the complete authorization. System.out.println("Authorization:\n"+"HMAC-SHA256 Signature="+signature+",Nonce="+nonce+",Timestamp="+timestamp); } /** * Create a Base64-encoded signature using the HMAC-SHA256 for the string data. * * @param secretKey Secret key * @param data String to be signed */ public static String hmacSHA256(String secretKey, String data) { try { Mac hmacSha256 = Mac.getInstance("HmacSHA256"); SecretKeySpec secretKeySpec = new SecretKeySpec(secretKey.getBytes(StandardCharsets.UTF_8), "HmacSHA256"); hmacSha256.init(secretKeySpec); byte[] hashBytes = hmacSha256.doFinal(data.getBytes(StandardCharsets.UTF_8)); return Base64.getEncoder().encodeToString(hashBytes); } catch (Exception e) { throw new RuntimeException("HmacSha error", e); } } /** * Calculate the MD5 digest of the string data and perform Base64 encoding on the digest to get the encoded result. * * @param data String to be calculated */ public static String md5(String data) { try { MessageDigest md = MessageDigest.getInstance("MD5"); md.reset(); md.update(data.getBytes(StandardCharsets.UTF_8)); String md5Result = String.format("%032x", new BigInteger(1, md.digest())); return Base64.getEncoder().encodeToString(md5Result.getBytes(StandardCharsets.UTF_8)); } catch (Exception e) { throw new RuntimeException("md5 error", e); } }}
The Client Generating and Passing Parameters
Pass the Authorization header and the Content-Type header at the client and send GET or POST requests to the server.
Authorization
For example,
HMAC-SHA256 Signature=FiXSVh+oBzitw+HDypwlmB0PE+Z67pdXbQM7QyHA7qk=, Nonce=c967a237-cd6c-470e-906f-a8655461897, Timestamp=1686542039670.
Content-Type
Enter the Content-Type header according to the request's content type.
You do not need to fill in the Content-Type header for GET requests.
The following figure shows the required items for generating the signature as the string to be signed. You need to replace the value of parameters marked with letters with actual values.
A
AppSecret
Choose Data Service > Application List, set App Authentication Method to Digest Signature, and you can copy the app secret, as shown in the following figure.
B
HTTPMethod
It is the request method. GET and POST requests are supported currently.
Nonce
It is a UUID, which is generated automatically in the Java code for signature generation.
During authentication, the server will use this UUID to check for duplicate requests within the last 5 minutes and intercept the duplicate request.
Timestamp
It is a 13-digit timestamp (the number of milliseconds since 1970-01-01 00:00:00 UTC), which is automatically generated in the Java code for signature generation.
During authentication, the server will use this timestamp to check whether the request has expired and block the expired request.
D
PathAndParameters
It is the API path configured on the API configuration page.
Include the parameter for GET requests.
For example, include the parameter <appid>/api01?a=1&b=2 in the API path: http://192.168.5.175:8089/webroot/service/publish/<appid>/api01?a=1&b=2
You can copy the API path from Authorized App in the API List, as shown in the following figure.
C
It is the MIME type of the request body.
For POST requests, specify the contentType. For GET requests, use an empty string here.
E
String data
It is the parameter string in the POST request body.
For requests with Content-Type application/json: Keep all strings as they are, including spaces, line breaks, and other symbols.
For requests with Content-Type application/x-www-form-urlencoded: Encode each key-value pair using URL encoding and join them with ampersands (&). Retain the equal sign (=) for keys without values and values without keys.
For example, the request body in the JSON format {"paging":{"pageSize":10,"pageNum":1},"params":[]} first experiences MD5 processing to output a 32-character lowercase string and then experiences Base64 encoding to output the final Content-MD5 result.
{"paging":{"pageSize":10,"pageNum":1},"params":[]}
The way to construct the string to be signed is as follows:
Nonce value "\n"
Timestamp value "\n"
PathAndParameters value "\n"
Content-Type value "\n"
Content-MD5 value
1. Each item is separated by a newline character (\n). If a particular item does not exist, it should be replaced by an empty string, while still preserving the newline character between items.
2. If there is no request body, the Content-MD5 value will be an empty string. (In other words, for GET requests, both the Content-Type and Content-MD5 values will be empty strings.)
Generate the signature from the string to be signed using the HMAC-SHA256 encryption algorithm.
Mac hmacSha256 = Mac.getInstance("HmacSHA256");byte[] appSecretBytes = appSecret.getBytes(Charset.forName("UTF-8"));hmacSha256.init(new SecretKeySpec(appSecretBytes, 0, appSecretBytes.length, "HmacSHA256"));byte[] md5Result = hmacSha256.doFinal(stringToSign.getBytes(Charset.forName("UTF-8")));String signature = Base64.encodeBase64String(md5Result);
The Server Receiving the Request
The method for calculating the signature is the same as that used on the client side.
Modify the specific content in the code by referring to the section "Java Implementation of Signatures" of this document.
For example, if you have published an API in FineDataLink with a request type of POST application/json, you need to prepare the following data to generate the string to be signed.
Content-MD5
For the BODY in the JSON format, you can copy the BODY value on the API generation page.
Run the Java file to obtain Authorization, as shown in the following figure.
The following takes a POST JSON request as an example. You can enter the Authorization value and the request body to fetch data from the published API, as shown in the following figure.
滑鼠選中內容,快速回饋問題
滑鼠選中存在疑惑的內容,即可快速回饋問題,我們將會跟進處理。
不再提示
10s後關閉
Submitted successfully
Network busy