Nie mogę zrozumieć znaczenia zmiennej oznaczonej na czerwono:
Macie jakieś pomysły? Potrzebuję tego do celu autoryzacji
Nie mogę zrozumieć znaczenia zmiennej oznaczonej na czerwono:
Macie jakieś pomysły? Potrzebuję tego do celu autoryzacji
A do czego służy? Bo wygląda, że szyfrujesz jakąś treść skamłająca się z url, użytkownika, nazwy klucza i jakieś zawartości, jaką chcesz gdzieś wysłać.
Stworzyłem taką metodę (nie wiem czy jest poprawna jeszcze) aby dodać do nagłówka autoryzacji w postmanie
public class iFirmaServiceOptions
{
public string faktura_key { get; set; }
public string abonent_key { get; set; }
public string rachunek_key { get; set; }
public string wydatek_key { get; set; }
public string userName { get; set; }
public enum eKeyType
{
faktura_key,
abonent_key,
rachunek_key,
wydatek_key
}
internal string GetKey(eKeyType keyType)
{
switch(keyType)
{
case eKeyType.faktura_key:
return faktura_key;
case eKeyType.abonent_key:
return abonent_key;
case eKeyType.rachunek_key:
return rachunek_key;
case eKeyType.wydatek_key:
return wydatek_key;
default:
throw new InvalidOperationException();
}
}
internal string GetKeyName(eKeyType keyType)
{
switch (keyType)
{
case eKeyType.faktura_key:
return "faktura";
case eKeyType.abonent_key:
return "abonent";
case eKeyType.rachunek_key:
return "rachunek";
case eKeyType.wydatek_key:
return "wydatek";
default:
throw new InvalidOperationException();
}
}
}
private string GenerateHMacSha1Hash(eKeyType key, string url, string requestContent)
{
HMACSHA1 sha = new HMACSHA1(Encoding.Default.GetBytes(options.GetKey(key)));
var hash = sha.ComputeHash(Encoding.Default.GetBytes(url + options.userName + options.GetKeyName(key) + requestContent));
return BitConverter.ToString(hash).Replace("-", "");
}
public void Test()
{
string url = "https://www.ifirma.pl/iapi/abonent/limit.json";
string hash = GenerateHMacSha1Hash(
eKeyType.abonent_key,
"https://www.ifirma.pl/iapi/abonent/limit.json",
"");
Debug.WriteLine(hash);
}
Korzystam z api https://api.ifirma.pl/naglowek-autoryzacji/
Nie wiem tylko czy podawać puste requestContent
czy jak?? Kiepsko opisane to API
w odpowiedzi dostaję:
STATUS 200
Jak ja to rozumiemy to nagłówek autoryzacyjnym ma być zakodowany request jak w ich dokumentacji. Jak wysalasz co ma body ( np PUT, POST ) to w request contente będziesz miał to, co wysyłasz w body (tak na chłopski rozum) . Po drugiej stronie oni pewnie robią to samo i pokonują hashe czy ktoś nie robi jakiś przekłamań w api.
Czyli to nic innego jak Body
? ;D Czyli w tym przypadku https://api.ifirma.pl/sprawdzanie-limitu-api/ body będzie puste.
Teraz metoda testowa:
public void Test()
{
string hash = GenerateHMacSha1Hash(
eKeyType.abonent_key,
"https://www.ifirma.pl/iapi/abonent/limit.json",
"");
Debug.WriteLine(hash);
}
Otrzymałem hash (Identyfikatory w opcjach są poprawne). przeklejam to do Postmana:
Nie dostaję błędu 401, ale mam niepoprawny hash. Macie pomysły?
No ale w twoim hashu nie widze ani nazwy użytkownika a, ani nazwy klucza (tak wynika z kodu).
ja to rozumiem tak:
hashWiadomosci=hmac(klucz, url + nazwaUsera + nazwaKlucza + requestContent)
klucz – wygenerowany klucz autoryzacji w postaci szesnastkowej
url – url, pod który przesyłane jest żądanie
nazwaUsera – login użytkowika do serwisu ifirma.pl
nazwaKlucza – identyfikator użytwgo klucza (wartość: abonent, faktura, rachunek lub wydatek)
requestContent – zawartość żądania
mam opcje zapisane w klasie:
private iFirmaServiceOptions options;
Tworzę instancję.
HMACSHA1 sha = new HMACSHA1(Encoding.Default.GetBytes(options.GetKey(key)));
Klucz options.GetKey(key)
pobieram z metody
internal string GetKey(eKeyType keyType)
{
switch(keyType)
{
case eKeyType.faktura_key:
return faktura_key;
case eKeyType.abonent_key:
return abonent_key;
case eKeyType.rachunek_key:
return rachunek_key;
case eKeyType.wydatek_key:
return wydatek_key;
default:
throw new InvalidOperationException();
}
}
Następnie hashuję podane dane:
var hash = sha.ComputeHash(
Encoding.Default.GetBytes(
url +
options.userName +
options.GetKeyName(key) +
requestContent));
Na koniec usuwam myślniki i otrzymuję 40 znaków hash
requestContent - to co chcesz wysłać , np. nagłówki albo html , cokolwiek (jeśli nie wysyłasz nić , to puste)
@FullSnack: A wiesz może, co w takim razie robię źle, że otrzymuję błąd "niepoprawny hash"? Próbowałem już na wszystkie sposoby. Do tej pory byłem przekonany, że to wina requestContent
, nie mam innych pomysłów
Zajrzyj w FAQ: https://api.ifirma.pl/faq/
Masz źle liczone byte z klucza. Według twojego kodu klucz z ifirmy np taki: EAB0D8ACF3308F3B bedzie mial 16 byteow, a powinien 8.
Tu masz działający przykład z FAQ
static void Main(string[] args)
{
var key = StringToByteArray("111111");
var message = Encode("222222", key);
}
public static byte[] StringToByteArray(string hex)
{
return Enumerable.Range(0, hex.Length)
.Where(x => x % 2 == 0)
.Select(x => Convert.ToByte(hex.Substring(x, 2), 16))
.ToArray();
}
public static string Encode(string input, byte[] key)
{
HMACSHA1 myhmacsha1 = new HMACSHA1(key);
byte[] byteArray = Encoding.ASCII.GetBytes(input);
MemoryStream stream = new MemoryStream(byteArray);
return myhmacsha1.ComputeHash(stream).Aggregate("", (s, e) => s + String.Format("{0:x2}", e), s => s);
}
W wyniku działania encode otrzymamy: cec153ee6350475f117a307111e2bd7d83034925