Żądanie HTTP z autentykacją

0

Dzień dobry,
Mam problem z połączeniem się z zewnętrznym API za pomocą skryptu PHP. Niestety zestawienie połączenia za pomocą tego skryptu nie działa. Problem jest podstawienie zmiennej typu string w miejsce klucza token i daty by za pomocą ich pobrać dane.

Poniżej kod jaki napisałem brakuje mi tylko funkcji lub poprawnej deklaracji zmiennych by wstawić klucz i czas, są one zadeklarowane jako $curl1 i $curl2.
Wpisanie klucza i daty wygenerowanej w programie Postman , działa. Więc kod sam w sobie jest prawidłowy. Oczywiście w kodzie poniżej NIE MA key i secret i url .

Dziękuję za pomoc.

<?php


$secret = '52';
$key = 'jcr';

function createHmacAuth($method, $path, $timestamp)
{
global $key, $secret;
$str = $method . ' ' . $path . $timestamp;
$hash = hash_hmac('sha256', $str, $secret);
return $key . ':' . $hash;
}

function getRequest($path)
{
$t = microtime(true);
$micro = sprintf("%03d", ($t - floor($t)) * 1000);
$time = gmdate('Y-m-d\TH:i:s.', $t) . $micro . 'Z';
$auth = createHmacAuth('POST', $path, $time);
echo $auth . "</pre>";
echo $time . "</pre>";
return $auth;
return $time;

}

$response = getRequest('');


$curl = curl_init();
$curl1 = curl_init($auth);
$curl2 = curl_init($time);
curl_setopt_array($curl, array(

CURLOPT_URL => 'https://...',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => '',
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 0,
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_POSTFIELDS => '{
"machineSns": [
"IL3"
],
"dateFrom": "2022-03-30T08:47:32.591",
"dateTo": "2022-09-24T05:47:32.591",
"startRow": 0,
"endRow": 10,
"selectedKpiTab": "",
"searchString": "DG15460"
}',

CURLOPT_HTTPHEADER => array(


'Content-Type: application/json',
'x-hp-hmac-authentication:' . $curl1 ,
'x-hp-hmac-date:' . $curl2 ,
'x-hp-hmac-algorithm: SHA256 '
),
));

$response = curl_exec($curl);

curl_close($curl);
echo $response;

3

Nie używaj zmiennych globalnych.

0

Poniżej kod z wpisanym kluczem i adresem wszystko działa. Niestety kod ma generować klucz automatycznie i to nie działa. Może ktoś ma jakieś rozwiązanie ?

<?php

function createHmacAuth($method, $path, $timestamp)
{
    $secret = '52mm';
    $key = 'jcri';
    $str = $method . ' ' . $path . $timestamp;
    $hash = hash_hmac('sha256', $str, $secret);
    return $key . ':' . $hash;
}

function getRequest($path)
{
    $t = microtime(true);
    $micro = sprintf("%03d", ($t - floor($t)) * 1000);
    $time = gmdate('Y-m-d\TH:i:s.', $t) . $micro . 'Z';
    $auth = createHmacAuth('POST', $path, $time);
    echo $auth . "</pre>";
    echo("<br>");
    echo("<br>");
    echo $time . "</pre>";
    return $auth;

}
function getRequest1($path2)
{
    $t = microtime(true);
    $micro = sprintf("%03d", ($t - floor($t)) * 1000);
    $time = gmdate('Y-m-d\TH:i:s.', $t) . $micro . 'Z';
    $auth = createHmacAuth('POST', $path2, $time);
    echo $auth . "</pre>";
    echo("<br>");
    echo("<br>");
    echo $time . "</pre>";
    return $time;

}

$response = getRequest('');

$curl = curl_init();

curl_setopt_array($curl, array(

    CURLOPT_URL => 'https://',
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_ENCODING => '',
    CURLOPT_MAXREDIRS => 10,
    CURLOPT_TIMEOUT => 0,
    CURLOPT_FOLLOWLOCATION => true,
    CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
    CURLOPT_CUSTOMREQUEST => 'POST',
    CURLOPT_POSTFIELDS => '{
    "machineSns": [
        "IL4100T018"
    ],
    "dateFrom": "2022-03-30T08:47:32.591",
    "dateTo": "2022-09-24T05:47:32.591",
    "startRow": 0,
    "endRow": 10,
    "selectedKpiTab": "",
    "searchString": "DG0000020",
    "sortExpression": "jobName"
}',

    CURLOPT_HTTPHEADER => array(


        'Content-Type: application/json',
        'x-hp-hmac-authentication:' . 'key' ,
        'x-hp-hmac-date:' . 'data' ,
        'x-hp-hmac-algorithm: SHA256'
    ),
));

$response = curl_exec($curl);

curl_close($curl);
echo $response;
1

Rozumiesz jak bez sensu to brzmi? wpisujesz klucz zeby program dzialal, a jego dzialanie ma polegac na generowaniu klucza. getRequest1 sie niczym nie rozni od getRequest

2

Przed curl_exec wykonaj curl_setopt pierwszy parametr to $curl drugi CURLOPT_HTTPHEADER a trzeci to tablica, którą masz teraz na sztywno ustawioną z podstawionymi do 'x-hp-hmac-authenticatioix-hp-hmac-date` odpowiednimi wartościami. Zakładając że ten zlepek kodu, którego nie za bardzo wiesz jak użyć jest poprawny tablicę nagłówków możesz mniej więcej otrzymać wywołując przykładową funkcję:

    function getOptionalHeaders($method, $path) {
        $secret = 'coś';
        $key = 'coś';
        $t = microtime(true);
        $micro = sprintf("%03d", ($t - floor($t)) * 1000);
        $time = gmdate('Y-m-d\TH:i:s.', $t) . $micro . 'Z';
        $str = $method . ' ' . $path . $time;
        $hash = hash_hmac('sha256', $str, $secret);
        $auth = $key . ':' . $hash;
        return  array('Content-Type: application/json',
                    'x-hp-hmac-authentication: ' . $auth,
                    'x-hp-hmac-date: ' . $time,
                    'x-hp-hmac-algorithm: SHA256');
    }

    //czyli ogólnie coś w stylu
    //...
    $headers = getOptionalHeaders('POST', '/');
    curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
    $response = curl_exec($curl);
    //...
0
kAzek napisał(a):

Przed curl_exec wykonaj curl_setopt pierwszy parametr to $curl drugi CURLOPT_HTTPHEADER a trzeci to tablica, którą masz teraz na sztywno ustawioną z podstawionymi do 'x-hp-hmac-authenticatioix-hp-hmac-date` odpowiednimi wartościami. Zakładając że ten zlepek kodu, którego nie za bardzo wiesz jak użyć jest poprawny tablicę nagłówków możesz mniej więcej otrzymać wywołując przykładową funkcję:

    function getOptionalHeaders($method, $path) {
        $secret = 'coś';
        $key = 'coś';
        $t = microtime(true);
        $micro = sprintf("%03d", ($t - floor($t)) * 1000);
        $time = gmdate('Y-m-d\TH:i:s.', $t) . $micro . 'Z';
        $str = $method . ' ' . $path . $time;
        $hash = hash_hmac('sha256', $str, $secret);
        $auth = $key . ':' . $hash;
        return  array('Content-Type: application/json',
                    'x-hp-hmac-authentication: ' . $auth,
                    'x-hp-hmac-date: ' . $time,
                    'x-hp-hmac-algorithm: SHA256');
    }

    //czyli ogólnie coś w stylu
    //...
    $headers = getOptionalHeaders('POST', '/');
    curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
    $response = curl_exec($curl);
    //...

Dziękuję za cenną uwagę sprawdzę ten sposób.

Obecnie po wprowadzeniu od wczoraj zmian otrzymuje informacje o braku dostępu do danych:

{"smsError":{"statusCode":401,"message":"Access denied for this resource","moreInfoUrl":"","developerInfo":"","subCode":0,"serviceName":"Printbeat"}}

Kod który to wywołuje poniżej, myślę że problemem jest sam wygenerowany token-klucz lub czegoś mi jeszcze pracuje w nagłówku.

global $token, $data;

function createHmacAuth($method, $path, $timestamp)
{
    $secret = '';
    $key = '';
    $str = $method . ' ' . $path . $timestamp;
    $hash = hash_hmac('sha256', $str, $secret);
    return $key . ':' . $hash;
}

function getRequest($path)
{
    $t = microtime(true);
    $micro = sprintf("%03d", ($t - floor($t)) * 1000);
    $time = gmdate('Y-m-d\TH:i:s.', $t).$micro.'Z';
    $auth = createHmacAuth('POST', $path, $time);
    echo $time . "</pre>";
    echo("<br>");
    echo $auth . "</pre>";
    echo("<br>");
    echo("<br>");
    return $auth;
}

$response = getRequest('');
$auth = $token;
$time = $data;
$curl = curl_init();
curl_setopt_array($curl, array(

    CURLOPT_URL => 'https:',
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_ENCODING => "",
    CURLOPT_MAXREDIRS => 10,
    CURLOPT_CONNECTTIMEOUT =>  0,
    CURLOPT_TIMEOUT => 0,
    CURLOPT_FOLLOWLOCATION => true,
    CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
    CURLOPT_CUSTOMREQUEST => 'POST',
    CURLOPT_POSTFIELDS => '{
    "machineSns": [
        "IL4100T018"
    ],
    "dateFrom": "2022-03-30T08:47:32.591",
    "dateTo": "2022-09-24T05:47:32.591",
    "startRow": 0,
    "endRow": 10,
    "selectedKpiTab": "",
    "searchString": "DG0000020",
    "sortExpression": "jobName"
}',

    CURLOPT_HTTPHEADER => array(
        "Content-Type: application/json",
        "x-hp-hmac-authentication: " . $token,
        "x-hp-hmac-date: " . $data ,
        "x-hp-hmac-algorithm: SHA256",
        'method' => 'POST'

    ),

));
$response = curl_exec($curl);
curl_close($curl);
$file = fopen("Data_HP/Data.xml","w");
$txt = $response;
fwrite($file, $txt);
fclose($file);
echo $response;



1
chomikowski napisał(a):

Rozumiesz jak bez sensu to brzmi? wpisujesz klucz zeby program dzialal, a jego dzialanie ma polegac na generowaniu klucza.

Ja nie rozumiem. Działanie programu nie ma polegać na generowaniu klucza, tylko na komunikacji z zewnętrznym API, które wymaga podania kodu HMAC.
A to, że potrzebny jest sekret do wygenerowania kodu HMAC, to po prostu skutek tego jak budowany jest HMAC ¯\_(ツ)_/¯

Serwer i klient mają współdzielony symetryczny sekret, klient żeby wysłać wiadomość do serwera musi dorzucić do nagłówków odpowiednio przygotowany HMAC. Nawet jak ktoś po drodze rozszyfruje TLS i i odczyta wiadomość w plaintextcie to nie będzie w stanie wysyłać spreparowanych przez siebie wiadomości do serwera, bo wciąż nie ma dostępu do sekretu.

1

Wszystko jak najbardziej działa przykładowy pełny kod (nie chciało mi się dynamicznie dodawać pól POST zostawiłam jak ty na sztywno).

<?php
    function getOptionalHeaders($method, $path) {
        $secret = 'tu wstaw swój';
        $key = 'tu wstaw swój';
        $t = microtime(true);
        $micro = sprintf("%03d", ($t - floor($t)) * 1000);
        $time = gmdate('Y-m-d\TH:i:s.', $t) . $micro . 'Z';
        $str = $method . ' ' . $path . $time;
        $hash = hash_hmac('sha256', $str, $secret);
        $auth = $key . ':' . $hash;
        return  array('Content-Type: application/json',
                    'x-hp-hmac-authentication: ' . $auth,
                    'x-hp-hmac-date: ' . $time,
                    'x-hp-hmac-algorithm: SHA256');
    }

	$curl = curl_init();
	curl_setopt_array($curl, array(

		CURLOPT_URL => 'https://printos.api.hp.com/printbeat/externalApi/gsb/scitexJobs/records?unitSystem=Metric',
		CURLOPT_RETURNTRANSFER => true,
		CURLOPT_ENCODING => "",
		CURLOPT_MAXREDIRS => 10,
		CURLOPT_CONNECTTIMEOUT =>  0,
		CURLOPT_TIMEOUT => 0,
		CURLOPT_FOLLOWLOCATION => true,
		CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
		CURLOPT_CUSTOMREQUEST => 'POST',
		CURLOPT_POSTFIELDS => '{
		"machineSns": [
			"IL4100T018"
		],
		"dateFrom": "2022-03-30T08:47:32.591",
		"dateTo": "2022-09-24T05:47:32.591",
		"startRow": 0,
		"endRow": 10,
		"selectedKpiTab": "",
		"searchString": "DG0000020",
		"sortExpression": "jobName"
	}'
	));
	
    $headers = getOptionalHeaders('POST', '/externalApi/gsb/scitexJobs/records');
    curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
	$response = curl_exec($curl);
	
	curl_close($curl);

	echo "<pre>";

	var_dump($response);

	echo "</pre>";
?>

Odpowiedź:

{"count":1,"totalSqm":221087.66,"totalPrintedBoards":150483,"jobs":[{"machineSN":"IL4100T018","jobName":"DG0000020_5799488_DRUK.pdf_1.1994","jobStartDate":"2022-09-14T00:00:00.000+00:00","printRuns":2,"aborts":0,"jobStart":"2022-09-14T11:14:52.687+00:00","jobEnd":"2022-09-14T11:19:25.230+00:00","jobPrintDuration":3.03,"totalSQM":20.8059,"printedBoards":12,"ejectedBoards":0,"totalInk":0.0394,"loadedBoards":12,"rowUpdateDate_Max":"2022-09-14T09:20:50.653+00:00","fluteList":"E","totalLinearMeter":20.976,"totalBA":0.0055,"substrateLength":1.085,"substrateWidth":1.598,"substrateName":"Gplus E Flute","totalYellow":0.0221,"totalMagenta":0.0065,"totalCyan":0.0094,"totalBlack":0.0014,"totalLightMagenta":0.0,"totalLightCyan":0.0}],"scitexKpis":{"totalJobName":550,"segment1":423,"segment2":86,"segment3":41,"segment4":0.947792,"segment5":0.033019,"segment6":0.0,"segment7":0.019188},"statusId":0,"statusDescription":"OK"}

PS: Radzę wyedytuj twój post z kluczami i usuń je.

1 użytkowników online, w tym zalogowanych: 0, gości: 1