API
Application programming interface alebo skratkou API je rozhranie pre prácu s ReFISom z iného programu. Momentálne je podporovaná verzia API 1.0.
Overovanie
V ReFISe si opíšte „API key ID“ a tajný kľúč „SecretKeyID“. ReFIS API využíva autentifikáciu cez HMAC, ktorá vyzerá nasledovne:
- Je nutné v každom requeste poslať HTTP hlavičku:
- "Authorization"
- "Date"
- Príklad:
- Authorization: ReFIS db000:4:Dr5v5iqDg1bsp0NJDdmCiqmXhyA=.
- Date: Mon, 15 Jan 2018 14:20:08 GMT
- Date obsahuje RFC2616 sformátovaný dátum
- Hodnoty hlavičky Authorization pozostávajú z:
- Service label ReFIS
- Meno spoločnosti
- API key ID
- Hash, ktorý sa vypočíta takto:
base64(sha1(upperstring(httpmethod) + "\n" + request_uripath + "\n" + httpheader_date_unixtime + "\n" + SecretKeyID))
Na otestovanie overovania môžete použiť end-point /api/1.0/authorization/. V prípade úspechu príde JSON odpoveď s textom: „You are authorized! Welcome!“
Operácie
Je možné vykonávať všetky operácie, ktoré môže robiť používateľ. „API key ID“ sa viaže ku kontu používateľa a operácie sa vykonávajú pod týmto používateľom. To znamená, že ak má používateľ napríklad prístup k operácii „Odoslať doklad“, môže API odoslať doklad.
Všetky operácie sú zdokumentované vo formáte SWAGGER na adrese: https://app.swaggerhub.com/api/ReFIS/re-fis_api/1.0
Vzorové implementácie
Java/Groovy
import grails.plugins.rest.client.RestBuilder import grails.util.Holders import org.apache.http.client.methods.HttpUriRequest import org.grails.web.json.JSONObject import org.springframework.http.HttpMethod import org.springframework.http.client.HttpComponentsClientHttpRequestFactory import org.springframework.web.client.RestTemplate import java.security.MessageDigest import java.time.ZonedDateTime import java.time.format.DateTimeFormatter class ReFISUtilService { private sendGetRequestToReFIS(RefisEndpoint endpoint, String company, LinkedHashMap payload = null, String param = null) { def headerDate = getDate() def response = this.restBuilder.get(getServerAddress() + getEndpoint(endpoint, param)) { header 'Authorization', getAccessTokenSHA1(headerDate, endpoint, "GET", company, param) header 'Date', headerDate.formatedTime header 'User-Agent', "yourservice/useragent" accept JSONObject, 'application/json' contentType('application/json') if(payload) json(payload) } def details = [body: response.body, response: response] def json = response.json if(response.responseEntity.statusCode.value in [200,201,202]) { return [response: json] } else if(response.responseEntity.statusCode.value == 400) { return [response: json, withError: true] } else { throw new IllegalStateException("[ReFIS API] Endpoint responded with status ${response?.responseEntity?.statusCode?.value}. Payload: $payload, response: $json, details: $details.") } } protected String getServerAddress() { return "https://dev.refis.sk" } private getEndpoint(RefisEndpoint endpoint, String param = null) { switch(endpoint) { case RefisEndpoint.AUTHORIZATION : return "/api/1.0/authorization" } } private getDate() { def date = ZonedDateTime.now() return [ unixTime: date.toEpochSecond().toString(), formatedTime: date.format(DateTimeFormatter.RFC_1123_DATE_TIME) //RFC2616 - rfc1123 give same result // Mon, 15 Jan 2018 14:20:08 GMT ] } private getInputString(headerDate, RefisEndpoint endpoint, String httpMethod, String param) { return httpMethod.toUpperCase()+"\n"+getEndpoint(endpoint, param)+"/\n"+headerDate+"\n"+config.refis.secretKey } private getAccessTokenSHA1(headerDate, RefisEndpoint endpoint, String httpMethod, String company, String param) { company = company ?: "testDB" MessageDigest sha1 = MessageDigest.getInstance("SHA1") return "ReFIS "+ company + ":" + config.refis.apiKeyID + ":" + Base64.encoder.encodeToString(sha1.digest(getInputString(headerDate.unixTime, endpoint, httpMethod, param).getBytes())) } def testAuthorization(String company) { def result = sendGetRequestToReFIS(RefisEndpoint.AUTHORIZATION, company,null) return result && !result.withError } } enum RefisEndpoint { AUTHORIZATION }
PHP
Kód je pre úpravu dátumu dodania v objednávke, iné end-pointy fungujú podobne.
<?php $serviceLabel = 'ReFIS'; $AccDocumentID = 999999; // ID dokladu $endpoint = "/api/1.0/accdocument/order/" . $AccDocumentID . '/'; $path = "https://dev.refis.sk" . $endpoint; $method = 'put'; $date = mktime(date("H"), 0, 0); $company = 'db004'; // nazov spolocnosti // API kluc $apikey = [ 'ID' => 1, // Identifikator 'Key' => 'cg1KmVAXDPBMGa86FAWy9123' // Kluc ]; // Vypocet hash-u $hash = base64_encode(sha1( strtoupper($method) . "\n" . $endpoint . "\n" . $date . "\n" . $apikey['Key'], TRUE)); $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $path); curl_setopt($ch, CURLOPT_HEADER, FALSE); curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE); curl_setopt($ch, CURLOPT_CUSTOMREQUEST, strtoupper($method)); curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode([ 'DeliveryDate' => '01.10.2018' // datum dodania ])); curl_setopt_array($ch, [ CURLOPT_HTTPHEADER => [ sprintf("authorization: %s %s:%d:%s", $serviceLabel, $company, $apikey['ID'], $hash), 'date: ' . date('r', $date), ], CURLOPT_RETURNTRANSFER => TRUE, CURLOPT_VERBOSE => 1, CURLOPT_FOLLOWLOCATION => 1 ]); $server_output = curl_exec($ch); print_r(json_decode($server_output)); curl_close($ch);
C#
using System.Net; using System.Text; public class ReFISAPI { //... your code here public async Task Authorization() { // Execute Authorization CreateHeader(HttpMethod.Get, RefisApiUrlEndpoints.AuthorizationUrl); var response = await SendAsync(HttpMethod.Get, _refisApiProxySetting.Endpoint + RefisApiUrlEndpoints.AuthorizationUrl, null); // Response Authorization with StatusCode: response.StatusCode var json = await response.Content.ReadAsStringAsync(); if (response.StatusCode != HttpStatusCode.OK) { _logger.LogError(json); throw new Exception("Authorization Error"); } } private string GetAuthorizationHash(HttpMethod httpMethod, string methodUrl, string dateUnix) { var key = httpMethod.ToString().ToUpperInvariant() + "\n" + methodUrl + "\n" + dateUnix + "\n" + _refisApiProxySetting.SecretKey; var sha = System.Security.Cryptography.SHA1.Create(); byte[] bytes = Encoding.UTF8.GetBytes(key); var hash = sha.ComputeHash(bytes); return Convert.ToBase64String(hash); } private string CreateAuthotizationHeader(HttpMethod httpMethod, string methodUrl, string dateUnix) { var hash = GetAuthorizationHash(httpMethod, methodUrl, dateUnix); return $ "ReFIS {_refisApiProxySetting.CompanyName}:{_refisApiProxySetting.ApiKeyId}:{hash}"; } private void CreateHeader(HttpMethod httpMethod, string methodUrl) { _httpClient.DefaultRequestHeaders.Clear(); var currentTime = DateTime.UtcNow; var dateHeader = currentTime.ToString("r"); var dateUnix = ((DateTimeOffset) currentTime).ToUnixTimeSeconds(); var authorization = CreateAuthotizationHeader(httpMethod, methodUrl, dateUnix.ToString()); _httpClient.DefaultRequestHeaders.Add("Authorization", authorization); _httpClient.DefaultRequestHeaders.Add("Date", dateHeader); } }
VB.NET
Tento kód slúži iba na vygenerovanie informácie do Header v HTTP requeste (Authorization: authorizationHeader, Date: dateHeader)
Dim authStaticVal As String = "ReFIS COMPANY_NAME_PLACEHOLDER:API_KEY_ID_PLACEHOLDER:" Dim secretKey As String = "SECRET_KEY_ID_PLACEHOLDER" Dim httpMethod As String = "GET" Dim methodUrl As String = "/api/1.0/authorization/" Dim currentUtcTime As DateTime = DateTime.UtcNow unixTimestamp = CLng((currentUtcTime - New DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc)).TotalSeconds).ToString() Dim key As String = httpMethod.ToString().ToUpperInvariant() & vbLf & methodUrl & vbLf & unixTimestamp & vbLf & secretKey Dim sha As System.Security.Cryptography.SHA1 = System.Security.Cryptography.SHA1.Create() Dim bytes() As Byte = System.Text.Encoding.UTF8.GetBytes(key) Dim hash() As Byte = sha.ComputeHash(bytes) authorizationHeader = authStaticVal & Convert.ToBase64String(hash) dateHeader = currentUtcTime.ToString("ddd, dd MMM yyyy HH:mm:ss 'GMT'")
Python
import time from datetime import datetime import hashlib import base64 import requests def generate_auth_header(http_method, request_uri, api_key_id, secret_key_id, company_name): date_header = datetime.utcnow().strftime('%a, %d %b %Y %H:%M:%S GMT') unix_timestamp = str(int(time.time())) string_to_hash = http_method.upper() + "\n" + request_uri + "\n" + unix_timestamp + "\n" + secret_key_id hashed = hashlib.sha1(string_to_hash.encode('UTF-8')) base64_encoded_hash = base64.b64encode(hashed.digest()).decode('utf-8') authorization_value = "ReFIS" + " " + company_name + ":" + api_key_id + ":" + base64_encoded_hash print("string_to_hash", string_to_hash) print(f"Authorization: {authorization_value} \n Date: {date_header}") return {"Authorization": authorization_value, "Date": date_header} headers = generate_auth_header("GET", "/api/1.0/authorization/", "API_KEY_ID_PLACEHOLDER", "SECRET_KEY_ID_PLACEHOLDER", "COMPANY_NAME_PLACEHOLDER") URL = "https://app1.refis.sk" response = requests.get(URL, headers=headers) print(f"HTTP response: {response.status_code} {response.content.decode('utf-8')}")