Я прочитал документацию по rfc7616 (
https://datatracker.ietf.org/doc/html/rfc7616), но у меня не получается выполнить второй запрос в рамках одной авторизации. Насколько я понимаю, я должен сделать нулевой (пустой) запрос, затем получить nonce из ответа, посчитать A1 и A2, а затем, с полученным заголовком, сделать первый запрос. В последующих запросах я должен увеличить NC и изменить URI.
- Я делаю пустой запрос.
- Получаю ответ 401 и nonce.
- Я вычисляю ответ, A1 и A2.
- Я делаю первый запрос.
- Получаю ответ 200.
- Я меняю URI, NC и считаю новый ответ.
- Я получаю ответ 401 stale=true
По какой-то причине второй запрос возвращает мне ошибку 401 и stale=true. Подскажите пожалуйста, я где-то ошибся или проблема в сервере?
$urlcam = 'http://website.com';
$username = 'admin';
$password = 'password';
function request($url, $header) {
$request_header = array($header);
$request_header[] = 'Accept: */*';
$ch = curl_init($GLOBALS['urlcam'].$url);
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => 1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPAUTH => CURLAUTH_DIGEST,
CURLOPT_HTTPHEADER => $request_header,
CURLOPT_HEADER => true
]);
$response = curl_exec($ch);
$info = curl_getinfo($ch);
curl_close($ch);
return ["res" => $response, "info" => $info];
}
function authparse($data) {
preg_match('/WWW-Authenticate: Digest (.*)/', $data, $matches);
$auth_header_array = explode(',', $matches[1]);
$result = [];
foreach ($auth_header_array as $pair) {
$vals = explode('=', $pair);
$result[trim($vals[0])] = trim(trim($vals[1]),'"');
}
return $result;
}
$start = date("Y-m-d%20H:i:s", strtotime('18.07.2022 09:00:00'));
$end = date("Y-m-d%20H:i:s", strtotime('18.07.2022 18:00:00'));
##################################################################################
##################################################################################
##################################################################################
# Empty request
$urlCreate = "/cgi-bin/mediaFileFind.cgi?action=factory.create";
$resultCreate = request($urlCreate, '');
##################################################################################
##################################################################################
##################################################################################
# First request
$resultCreateParse = authparse($resultCreate['res']);
$realm = $resultCreateParse['realm'];
$qop = $resultCreateParse['qop'];
$opaque = $resultCreateParse['opaque'];
$nonce = $resultCreateParse['nonce'];
$cnonce = "0a4f113b";
$nc = "00000001";
$a1 = md5($username.":".$realm.":".$password);
$a2 = md5("GET:".$urlCreate);
$a3 = md5($a1.':'.$nonce.':'.$nc.':'.$cnonce.':'.$qop.':'.$a2);
$headerCreate = 'Authorization: Digest username="'.$username.'",realm="'.$realm.'",nonce="'.$nonce.'",uri="'.$urlCreate.'",cnonce="'.$cnonce.'",nc='.$nc.',response="'.$a3.'",qop="'.$qop.'",opaque="'.$opaque.'"';
$resultCreate = request("$urlCreate", $headerCreate);
$id = explode('result=',trim($resultCreate['res']))[1];
##################################################################################
##################################################################################
##################################################################################
# Second request
$urlFindFile = "/cgi-bin/mediaFileFind.cgi?action=findFile&condition.Channel=1&condition.StartTime=$start&condition.EndTime=$end&condition.Types[0]=dav&object=$id";
$cnonce = "0a4f113b";
$nc = "00000002";
$a1 = md5($username.":".$realm.":".$password);
$a2 = md5("GET:".$urlFindFile);
$a3 = md5($a1.':'.$nonce.':'.$nc.':'.$cnonce.':'.$qop.':'.$a2);
$headerFindFile = 'Authorization: Digest username="'.$username.'",realm="'.$realm.'",nonce="'.$nonce.'",uri="'.$urlFindFile.'",cnonce="'.$cnonce.'",nc='.$nc.',response="'.$a3.'",qop="'.$qop.'",opaque="'.$opaque.'"';
$resultFindFile = request($urlFindFile, $headerFindFile);