Frage zu curl

Hallo,

ich versuche mich gerade an curl und dem Login zur Alexa Seite.

Wenn ich unter ubuntu den folgenden curl Befehl absetze


curl -L https://alexa.amazon.de 

dann bekomme ich die gewünschte Ausgabe:



<!doctype html><html class="a-no-js a-touch a-mobile" data-19ax5a9jf="mongoose">
  <head><script>var aPageStart = (new Date()).getTime();</script><meta name="viewport" content="width=device-width, maximum-scale=1, minimum-scale=1, initial-scale=1, user-scalable=no, shrink-to-fit=no"><meta charset="utf-8">
    <title dir="ltr">Amazon Anmelden</title>
    <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=0" />

    
      
        <link rel="stylesheet" href="https://images-na.ssl-images-amazon.com/images/G/01/AUIClients/AuthenticationPortalAlexaSkin-c4ded2ae98d55d0c903a85316db66fa58d24144b._V2_.css#AUIClients/AuthenticationPortalAlexaSkin.device_type-mobile.us.rendering_engine-not-trident.secure.min" />
<link rel="stylesheet" href="https://images-na.ssl-images-amazon.com/images/G/01/AUIClients/AuthenticationPortalAssets-d4fd5fbdd290721e3fd697fb54a12b8611adbc6f._V2_.css#AUIClients/AuthenticationPortalAssets.device_type-mobile.secure.min" />
<link rel="stylesheet" href="https://images-na.ssl-images-amazon.com/images/G/01/AUIClients/CVFAssets-807886b3afc932f042672cf115a85b51c30a5ed4._V2_.css#AUIClients/CVFAssets.device_type-mobile.secure.min" />

        <script>
........

Versuche ich das unter PHP

$ch = curl_init();

curl_setopt($ch, CURLOPT_URL, "https://alexa.amazon.de");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);

$result = curl_exec($ch);
if (curl_errno($ch)) {
    echo 'Error:' . curl_error($ch);
}
echo json_encode($result);

curl_close ($ch);

dann bleibt die Ausgabe leer (""). Hat da jemand einen Rat für mich, wie ich curl zur gewünschten Ausgabe bringen kann?

Gruß

Burkhard

füg mal das hinzu


curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);

bei einem Test bei mir gab’s auf jeden Fall Output zurück…

Was sucht das echo json_encode($result); da im Code wenn du doch HTML erwartest?
Json_encode wirft keine Fehler wenn es einen ungültigen String bekommt.
Michael

das ist natürlich richtig, das hatte ich bei meinen Test auch schon durch ein reines ‚echo $result‘ ersetzt. hatte ich in meiner Antwort vergessen zu schreiben.

ohne FOLLOWACTION ist result leer, mit steht html-code drin.

Was willst Du den genau machen? Den ersten Cookie holen und analysieren?



function First_GetCookie()
{

//german
$url = "https://alexa.amazon.de";

//english
//$url = "https://alexa.amazon.com";


$sCookieFile = tempnam(sys_get_temp_dir(), 'Cookie_Alexa');
  var_dump($sCookieFile);

// open a site with cookies
$ch = curl_init();
// curl_setopt($ch, CURLOPT_URL, "http://www.google.com");
curl_setopt($ch, CURLOPT_URL, $url);

curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/5.0 (Windows NT 6.1; rv:11.0) Gecko/20100101 Firefox/11.0');
curl_setopt($ch, CURLOPT_HEADER  ,1);
curl_setopt($ch, CURLOPT_RETURNTRANSFER  ,1);
curl_setopt($ch, CURLOPT_COOKIESESSION, true);
curl_setopt($ch, CURLOPT_COOKIEJAR, $sCookieFile);  //could be empty, but cause problems on some hosts
curl_setopt($ch, CURLOPT_COOKIEFILE, $sCookieFile);  //could be empty, but cause problems on some hosts
curl_setopt($ch, CURLOPT_FOLLOWLOCATION  ,1);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
$content = curl_exec($ch);

// get header
$headers=array();

$data=explode("
",$content);
//var_dump($data);

$headers['status']=$data[0];
//var_dump($headers);

array_shift($data);
//var_dump($data);

foreach($data as $key => $part)
{
    $middle = strpos($part, ":");
	//var_dump($middle);
	if($middle)
	{
		$headertype = substr($part, 0, $middle);
		//var_dump($headertype);
		$headercontent = substr($part, $middle+2);
		//var_dump($headercontent);
		if(headertype($headertype))
		{
			$headers[$headertype] = $headercontent;
		}
	}
	
	
	//$middle = explode (":",$part);
	//var_dump($middle);
    //$headers[trim($middle[0])] = trim($middle[1]);
}

//print all headers as array
echo "<pre>";
print_r($headers);
echo "</pre>";


// get location
$location = $headers["Location"];
var_dump($location);
SetValue(39195 /*[Geräte\Amazon Echo Alexa\Amazon Steuerung\Location First Login]*/, $location);

// get cookies
$cookies = array();
preg_match_all('/Set-Cookie:(?<cookie>\s{0,}.*)$/im', $content, $cookies);

print_r($cookies['cookie']); // show harvested cookies

// basic parsing of cookie strings (just an example)
$cookieParts = array();
preg_match_all('/Set-Cookie:\s{0,}(?P<name>[^=]*)=(?P<value>[^;]*).*?expires=(?P<expires>[^;]*).*?path=(?P<path>[^;]*).*?domain=(?P<domain>[^\s;]*).*?$/im', $content, $cookieParts);
//print_r($cookieParts);


$amzcookie = $cookies['cookie'];

//Session ID
$session_id_info = GetSessionID($amzcookie);
$session_id = $session_id_info['session_id'];
$session_id_time = $session_id_info['session_id_time'];
// var_dump($session_id);
// var_dump($session_id_time);
SetValue(56031 /*[Geräte\Amazon Echo Alexa\Amazon Steuerung\Neuer Cookie Ansatz\Session ID First Login]*/, $session_id);
SetValue(34145 /*[Geräte\Amazon Echo Alexa\Amazon Steuerung\Neuer Cookie Ansatz\Session ID Time]*/, $session_id_time);






// Hidden Field suchen

// var_dump($content);
return $sCookieFile;
}

function headertype($headertype)
{
	$headertypes = array("x-amzn-RequestId", "Location", "Content-Length", "Date", "Server", "Content-Type", "Strict-Transport-Security", "x-ua-compatible", "Pragma", "Cache-Control", "Expires", "X-Frame-Options", "P3P", "Vary", "Date", "Transfer-Encoding", "Connection");
	if(in_array($headertype, $headertypes))
	{
		$useheadertype = true;
	}
	else
	{
		$useheadertype = false;
	}
	return $useheadertype;
}

function GetSessionID($amzcookie)
{
	$session_id_info = array();
	foreach ($amzcookie as $cookie)
	{
		$pos_session_id_start = strpos($cookie, "session-id=");
		
		//var_dump($pos_session_id_start);
		if($pos_session_id_start)
		{
			$pos_session_id_end = strpos($cookie, ";");
			//var_dump($pos_session_id_end);
			$session_id = substr($cookie, $pos_session_id_start+11, $pos_session_id_end-12);
			$session_id_info['session_id'] = $session_id;			
		}
		$pos_session_id_time_start = strpos($cookie, "session-id-time=");
		
		//var_dump($pos_session_id_start);
		if($pos_session_id_time_start)
		{
			$pos_session_id_time_end = strpos($cookie, ";");
			//var_dump($pos_session_id_end);
			$session_id_time = substr($cookie, $pos_session_id_time_start+16, $pos_session_id_time_end-17);
			$session_id_info['session_id_time'] = $session_id_time;			
		}
		//var_dump($pos_session_id_start);
	}
	return $session_id_info;
}

$first_cookie = First_GetCookie();
var_dump($first_cookie);

Problem ist wohin den Cookie in der Struktur von IP-Symcon speichern bzw. auf welches Verzeichnis hat IPS sinnvollerweise Zugriffsrechte in die man z.B. ein Temp Cookie ablegen könnte. Andere Möglichkeit wäre den Cookie zerlegen und nur die Teile abspeichern die man braucht. Insbesondere die Hidden Fields brauchst Du und das macht mir persönlich Probleme.
Aber wenn sich da da eine sinnvolle Lösung findet wäre das gut dann könnte man einen Timer laufen lassen der die wichtigen Daten einfach im Hintergrund erneuert.

Vielleicht ist ja hier etwas passendes dabei:



public function LoginToNello ()
{
$emailAddress = $this->ReadPropertyString ("EMailAddress");
$password = $this->ReadPropertyString ("Password");
if ($emailAddress != "" && $password != "") {
$timeout = $this->ReadPropertyInteger ("Timeout");
$postData = json_encode(array("username" => $emailAddress, "password" => $password)); 
$ch = curl_init();
$options = array(CURLOPT_URL => 'https://api.nello.io/login',
 CURLOPT_HEADER => true,
 CURLOPT_CUSTOMREQUEST => "POST",
 CURLOPT_POSTFIELDS => $postData,
 CURLOPT_RETURNTRANSFER => true,
 CURLOPT_AUTOREFERER => true,
 CURLOPT_COOKIESESSION => true,
 CURLOPT_FAILONERROR => false,
 CURLOPT_FOLLOWLOCATION => false,
 CURLOPT_FRESH_CONNECT => true,
 CURLOPT_CONNECTTIMEOUT => $timeout);
curl_setopt_array($ch, $options);
$result = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
// check connection
$connection = true;
if ($httpCode != 200) {
echo "Seite ist nicht erreichbar!
";
$connection = false;
}
curl_close($ch); 
// connection is established
if ($connection == true) {
// get session cookie
$pattern = "/^Set-Cookie:\s*([^
]*)/mi"; 
preg_match_all($pattern, $result, $matches); 
array_shift($matches); 
$cookie = implode("
", $matches[0]); 
$this->SetBuffer("CookieToken", $cookie);
IPS_LogMessage("Nello Cookie", $cookie);
// set timer for renewal
$interval = 86400000;
$this->SetTimerInterval ("CookieUpdate", $interval);
// check login 
$jsonString = preg_replace('/HTTP(.*)alive/s',"",$result);
$jsonObject = json_decode($jsonString);
$loginMessage = $jsonObject->result->message;
echo $loginMessage."
";
$authentication = $jsonObject->authentication; 
// login successful
if ($authentication == true) {
$configurationData = $jsonString;
}
else {
$configurationData = "";
}
$this->SetBuffer("ConfigurationData", $configurationData);
}
}
}

Habe ich mal bei einem Modul verwendet.

Gesendet von iPhone mit Tapatalk

Bingo. Das fehlte mir. Besten Dank!

Das ist nur als Testanweisung drin. Nutze ich gerne als Alternative zu echo und var_dump.

Ich versuche gerade, die login Sequenz aus dem LötzimmerSkript zu verstehen und umzusetzen. Ich bin noch beim ersten Schritt ‚get first cookie and write redirection target into referer‘.

Ich denke mit euren Tipps komme ich jetzt weiter. Besten Dank dafür. Mal sehen, wann das nächste Problem auftaucht :smiley:

Gruß

Burkhard

Ich drücke Dir die Daumen, ich hatte das mal angeschaut hatte aber Probleme den entscheidenden Teil des Cookies und den CRSF auszulesen. Wenn Dir das sauber gelingen sollte wäre das prima dann kann man sich das händische eintragen im PHP Modul sparen das würde dann das Modul selber machen.

Noch bin ich guter Dinge[emoji1]

Gemeinsam schaffen wir es bestimmt.