Create POST (protocol) for Wordpress from reading debugging tool Chrome - php

I have a button on my page WordPress to check or uncheck the post of WordPress as favorite. It is my intention to make a POST call from php to do this. Later I call this php from a mobile app.
My App Mobile ==> (get_favorito.php) POST (idUser, idPost, Status) ==> Favorite ON / OFF
I currently use WP 4.4.2 and Plugin for WordPress FAVORITES (https://github.com/kylephillips/favorites)
I launch the POST used the tool for developers of Chrome.
image important debugging
And I can see that the call is made:
http://web.domine.com/wp-admin/admin-ajax.php?action=simplefavorites_favorite&nonce=XXXXXXcd14&postid=273&siteid=1&status=inactive
or
http://web.domine.com/wp-admin/admin-ajax.php?action=simplefavorites_favorite&nonce=XXXXXXcd14&postid=273&siteid=1&status=active
My question comes with the part of Header and Cookie. How did you get this information?
I'm trying this, but it does not work.
This is the php I am writing.
<?php
$ruta = 'http://' . $_SERVER['HTTP_HOST'];
$json = file_get_contents($ruta . '/wp-admin/admin-ajax.php?action=simplefavorites_nonce');
$arr = json_decode($json, true);
$nonce = $arr['nonce'];
$opts = array(
'http'=>array(
'method'=>'POST',
'header'=> 'POST /wp-admin/admin-ajax.php HTTP/1.1\r\n' .
'Host: web.domine.com\r\n' .
'Connection: keep-alive\r\n' .
'Content-Length: 84\r\n' .
'Accept: */*\r\n' .
'Origin: http://web.domine.com\r\n' .
'X-Requested-With: XMLHttpRequest\r\n' .
'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/48.0.2564.116 Safari/537.36\r\n' .
'Content-Type: application/x-www-form-urlencoded; charset=UTF-8\r\n' .
'Referer: http://web.domine.com/hola-mundo-2/\r\n' .
'Accept-Encoding: gzip, deflate\r\n' .
'Accept-Language: es-ES,es;q=0.8\r\n' .
'Cookie: wordpress_dddd3333f97127bf3816f4455971ce5aa=peteradmin%7C1457085836%7CxWJrk7EQVEYRpZY9Jzev4fH6jx3cq97wx6LPaMd9C4v%7Cd232ca14edca535e653dd37607b754d78926410e317d34315cbcb5533cda08c8; PHPSESSID=8eda0049e17a67becb1c8fddd18c6c51;
wordpress_logged_in_dddd3333f97127bf3816f4455971ce5aa=peteradmin%7C1457085836%7CxWJrk7EQVEYRpZY9Jzev4fH6jx3cq97wx6LPaMd9C4v%7C63a7b53cfbb2c5a3b86e59c65e9977077e352ad8fe00228dee9b04a7a1e36ad9;
wp-settings-1=libraryContent%3Dbrowse%26editor%3Dtinymce%26mfold%3Do;
wp-settings-time-1=1456991866;
wordpress_test_cookie=WP+Cookie+check;
simplefavorites=%5B%7B%22site_id%22%3A1%2C%22posts%22%3A%7B%221%22%3A194%2C%222%22%3A208%2C%223%22%3A273%7D%7D%5D'
)
);
$context = stream_context_create($opts);
//
//
$param = "action=simplefavorites_favorite&nonce='.$nonce.'&postid=273&siteid=1&status=active";
$json = file_get_contents($ruta . '/wp-admin/admin-ajax.php?'.$param.'', false, $context);
echo $json;
?>
(I put spaces so that cookies are correctly displayed)
And now I get nonce with:
http://web.domine.com/wp-admin/admin-ajax.php?action=simplefavorites_nonce

Hello I was redirected here from nubelo in order to answer.
The headers are set automatically by the browser and the cookies are set by different pages of wordpress like the wp-login.php page.
The simplefavorites cookie is a cookie that stores an anonymoys user favorite posts array, and it is returned in the response headers of the wp-admin/admin-ajax.php?action=simplefavorites_array page. For logged in users the favorites information is returned in json format in the response of that same page.
I made a php script to toggle the status it just sends the cookies to the respective endpoints and you would only need to store the cookies in your mobile app and send them with your request.
https://gist.github.com/chaps/eec3769560c7d8debe59

Related

Using Curl in PHP

I am working on a project, to help me learn how to use curl through PHP. I am attempting to get data from the Twitch-API using my own account for testing.
I have successfully authenticated my account with my domain by using:
https://api.twitch.tv/kraken/oauth2/authorize?response_type=code&client_id=...&redirect_uri=...&scope=user_read+channel_read+channel_subscriptions+user_subscriptions+channel_check_subscription&state=...
I have removed client_id, redirect_uri and state to show the link I used.
Once successfully authenticated it returns back to a domain that I specify (redirect_uri), once it gets back to that domain the website only knows the authentication key that is generated once accepted by the user, from twitch.
Example auth: 3ofbaoidzkym72ntjua1gmrr66o0nd
Now I would like to be able to get the username of the user, there is documentation on it:
curl -H 'Accept: application/vnd.twitchtv.v3+json' -H 'Authorization: OAuth <access_token>' \
-X GET https://api.twitch.tv/kraken/user
I am attempting to do this in PHP, but I don't understand the curl functions... Here's what I've got so far:
<?php if(isset($_GET['code']) && isset($_GET['scope'])) { ?>
<pre>
<?php
$auth = $_GET['code'];
$twitch = curl_init();
$headers = array();
$headers[] = 'Accept: application/vnd.twitchtv.v3+json';
$headers[] = 'Authorization: OAuth ' .$auth;
curl_setopt($twitch, CURLOPT_HEADER, $headers);
curl_setopt($twitch, CURLOPT_URL, "https://api.twitch.tv/kraken/user");
curl_exec($twitch);
?>
</pre>
<?php }; ?>
When I attempt to run this section of code, I get some errors:
HTTP/1.1 401 Unauthorized
Server: nginx
Date: Sat, 08 Aug 2015 13:43:51 GMT
Content-Type: application/json; charset=utf-8
Content-Length: 89
Connection: keep-alive
Status: 401 Unauthorized
X-API-Version: 3
WWW-Authenticate: OAuth realm='TwitchTV'
Cache-Control: max-age=0, private, must-revalidate
Vary: Accept-Encoding
X-UA-Compatible: IE=Edge,chrome=1
X-Request-Id: 4bc2e0bfadf6817366b4eb19ab5751bf
X-Runtime: 0.007862
Accept-Ranges: bytes
X-Varnish: 1641121794
Age: 0
Via: 1.1 varnish
X-MH-Cache: rails-varnish-5cb970; M
{"error":"Unauthorized","status":401,"message":"Token invalid or missing required scope"}
But I am unsure on how to fix this problem as, to me, it seems I am/have done everything that the documentation says to do...
How should I go about fixing this issue?
Edit:
It seems to work if I request using my twitch username:
curl -H 'Accept: application/vnd.twitchtv.v3+json' \
-X GET https://api.twitch.tv/kraken/users/test_user1
My Code for using the username:
<?php
$auth = urlencode($_GET['code']);
$twitch = curl_init();
$headers = array();
$headers[] = 'Accept: application/vnd.twitchtv.v3+json';
#$headers[] = 'Authorization: OAuth ' .$auth;
curl_setopt($twitch, CURLOPT_HTTPHEADER , $headers);
curl_setopt($twitch, CURLOPT_URL, "https://api.twitch.tv/kraken/users/...");
curl_exec($twitch);
?>
But I wouldn't know the user's username unless I get it from the statement which is producing an error and store it in a database.
Edit:
Reading into the documentation abit more, it requires the scope as well as the access token. I have been able to get this:
Example:
Array
(
[0] => Accept: application/vnd.twitchtv.v3+json
[1] => Authorization: OAuth code=scn89zerug002sr6r95z9ngbxmd0d2&scope=user_read+channel_read+channel_subscriptions+user_subscriptions+channel_check_subscription
)
But I still get the error...
Edit:
So I read through the documentation EVEN MORE and now I have gotten to this:
class twitch {
var $base_url = "https://api.twitch.tv/kraken/";
var $client_id = "...";
var $client_secret = "...";
var $return_url = "...";
var $scope_array = array('user_read','channel_read','channel_subscriptions','user_subscriptions','channel_check_subscription');
public function get_access_token($code,$state) {
$ch = curl_init($this->base_url . "oauth2/token");
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POST, 1);
$fields = array(
'client_id' => $this->client_id,
'client_secret' => $this->client_secret,
'grant_type' => 'authorization_code',
'redirect_uri' => $this->redirect_url,
'code' => $code
);
curl_setopt($ch, CURLOPT_POSTFIELDS, $fields);
$data = curl_exec($ch);
$response = json_decode($data, true);
curl_close($ch);
echo "<pre>".print_r($this->redirect_url,true)."</pre>";
echo "<pre>".print_r($response,true)."</pre>";
return $response["access_token"];
}
};
$auth = new twitch();
print_r($auth->get_access_token($_GET['code'],$_GET['state']));
But this time there is another error, saying that my 'redirect_uri' => $this->redirect_url is different to the one which is held by twitch.
Array
(
[error] => Bad Request
[status] => 400
[message] => Parameter redirect_uri does not match registered URI
)
I have even copied and pasted from the twitch website to my variable and the other way around, I still get the same error... Now I'm even more stuck, but at least a step closer.
Right I'm going to do this with you as I do it :d So far I've been able to get one user, the reason you're getting errors is because you're not setting any curl options. I taught myself using this https://github.com/paypal/rest-api-curlsamples/blob/master/execute_all_calls.php which I found MASSIVELY helpful when learning curl. The code itself is basic but it's so easy to read. I managed to understand it and make it 100% more complicated :D
First things first, I'll show you how I got the test user.
What you want to do is set the options, I'll keep to the simple method first.
The 2 methods are CURLOPT_HEADER and CURL_RETURNTRANSFER. Your url you can set with the init function.
$twitch=curl_init('https://api.twitch.tv/kraken/users/test_user1');
curl_setopt($twitch,CURLOPT_HTTPHEADER,array('Accept: application/vnd.twitchtv.v3+json'));//must be an array.
curl_setopt($twitch,CURLOPT_RETURNTRANSFER,true);
$result=curl_exec($twitch);
$info=curl_getinfo($twitch);
print_r($result);
This will get you your test user and hopefully show you a little bit about what you're doing wrong. If you wanted to use the array method, then you must use your curl options as the array key so that the set function know what to set what as. (don't ask me how it all technically works :S)
I'll update to show you how to get an authorisation and data once I've worked it out. But the basic principles are you need to send post data and set CURLOPT_POST to true and include the postdata CURLOPT_POSTFIELDS which must be a json array as your application requires json I believe?
Anyway the array:
curl_set_opts($twitch,array(CURLOPT_HEADER=>array('Accept: application/vnd.twitchtv.v3+json',CURLOPT_RETURNTRANSFER=true));
Seeing as you already know how to authorise a user I'll skip that bit, although I'd recommend using something a little more secure than a $_GET. Maybe a session variable would be a bit better.
To get a specific user using the Auth that is returned. You want to do something like this: (Sorry I can't test it myself, I don't have a twitch dev account)
$twitch=curl_init('https://api.twitch.tv/kraken/user');
curl_setopt($twitch,CURLOPT_HEADER,array('Accept: application/cvd.twitchtv.v3+json','Authorization: OAuth '.$_SESSION['token']));
curl_setopt($twitch,CURLOPT_RETURNTRANSFER,true);
$result=curl_exec($twitch);
print_r($result);
//don't forget to close!
curl_close($twitch);
$user=json_decode($result);
echo$user->display_name;
That should work although I have no idea how you're getting a oAuth token lol
if you wanted to be a really cool programmer 8| I'd recommend doing some classes for this. Like this
class twitch{
private$token,$twitch,$url="http://api.twitch.tv/kraken/";
protected$code,$state,$report;
private static$details;
public function __construct($code,$state){
$this->code=$code;
$this->state=$state;
self::$details=(object)array('client_id'=>'id','client_secret'=>'secret','return_url'=>'redirect');
$result=$this->makeCall('oauth2/token',true);
print_r($result);
}
protected function makeCall($extention,$auth=false,$object=true){
$this->twitch=curl_init($this->url.$extention);
//$opts=array(CURLOPT_)
if($auth!==false){
$opts=array(CURLOPT_FOLLOWLOCATION=>true,CURLOPT_RETURNTRANSFER=>true,CURLOPT_POST=>true,CURLOPT_POSTFIELDS=>json_encode(array('client_id'=>self::$details->client_id,'client_secret'=>self::$details->client_secret,'grant_type'=>'authorization_code','code'=>$this->code,'redirect_uri'=>self::$details->return_url)));
}else{
$opts=array(CURLOPT_HEADER=>array('Accept: application/cvd.twitchtv.v3+json','Authorization: OAuth '.$this->token),CURLOPT_RETURNTRANSFER=>true);
}
curl_setopt_array($this->twitch,$opts);
$result=curl_exec($this->twitch);
$this->report=array('info'=>curl_getinfo($this->twitch),'error'=>curl_error($this->twitch));
curl_close($this->twitch);
return($object===true)?json_decode($result):$result;
}
protected function userDetails(){
return$this->makeCall('user');
}
public function user(){
return$this->userDetails();
}
}

Google Hotel Finder, file_get_contents PHP

I try to check if a hotel is available through the Google Hotel Finder. I use the following PHP code:
<?php
//get date, in the future with $_POST
//get source
$source = file_get_contents('https://www.google.co.uk/hotelfinder/#search;l=london;d=2015-08-14;n=1;usd=1;h=17709217511794056234;si=;av=d');
//"Book a room" only shows when room(s) are available
if (strpos($source, "Book a room") !== false) {
echo "Room(s) available";
} else {
echo "Nothing available";
}
echo $source;
?>
When I run this code in my server, Google Hotel Finder gives me the following error message: "Google Hotel Finder has not been optimised for your browser. For best results, please try Chrome, Firefox 3.5+, Internet Explorer 8+, Safari 4+".
So Google detected that I was visiting the page trough PHP... Is there an way to ignore or bypass this "block"?
You may try to send user agent info with header.
$options = array(
'http'=>array(
'method'=>"GET",
'header'=>"Accept-language: en\r\n" .
"Cookie: foo=bar\r\n" . // check function.stream-context-create on php.net
"User-Agent: Mozilla/5.0 (iPad; U; CPU OS 3_2 like Mac OS X; en-us) AppleWebKit/531.21.10 (KHTML, like Gecko) Version/4.0.4 Mobile/7B334b Safari/531.21.102011-10-16 20:23:10\r\n" // i.e. An iPad
)
);
$context = stream_context_create($options);
$file = file_get_contents($url, false, $context);
PHP file_get_contents() and headers

Setting useragent in PHP file_get_contents?

I am trying to get the content from a page using file_get_contents to get the HTML and regex for further processing.
The site I am getting my content from has a desktop and mobile site so I was wondering is there a way to send a custom useragent to get the mobile site instead of the desktop site?
Using file_get_contents I have tried it with my code shown below but all I get is a blank page:
$options = array(
'http'=>array(
'method'=>"GET",
'header'=>"Accept-language: en\r\n" .
"Cookie: foo=bar\r\n" .
"User-Agent: Mozilla/5.0 (iPad; U; CPU iPad OS 5_0_1 like Mac OS X; en-us) AppleWebKit/535.1+ (KHTML like Gecko) Version/7.2.0.0 Safari/6533.18.5\r\n" // i.e. An iPad )
);
$context = stream_context_create($options);
$file = file_get_contents('http://www.example.com/api/'.$atrib,false,$context);
$doc = new DOMDocument();// create new dom document
$doc->loadHTML($file);// load the xmlpage
$tags = $doc->getElementsByTagName('video'); // find the tag we are looking for
foreach ($tags as $tag) { // for ever tag that is the same make it a new tag of its own
if (isset($_GET['key']) && $_GET['key'] == $key) { // if key is in url and matches script key - do or dont
echo $tag->getAttribute('src'); // get out 3 min video from the attribute in page
} else { // if key is not in url or not correct show error
echo "ACCESS DENIED!"; // our out bound error
}
}
I am trying to get the useragent to load up the content from the sites mobile page and useing regex get the src url from this line of code in the page just in case this is the problem:
<video id="player" src="http://example.com/api/4.m3u8" poster="http://example.com/default.png" autoplay="" autobuffer="" preload="" controls="" height="537" width="935"></video>
As mentioned by Casimir et Hippolyte in the comments, uncomment the closing parenthesis at the end of the line of "User-Agent: Mozilla...:
ini_set('display_errors', 'On');

file_get_contents with header: Send current header or current cookie in magento or common

I want to call an URL and want to get the result with PHP by using file_get_contents (I know CURL, but first I want to try it with file_get_contents). In my case it's a request to the magento shop system, which requires a previously done login to the backend.
If I execute the URL manually in my browser, the right page is coming. If I send the URL with file_get_contents, I will also get logged in (because I added the Cookie to the request), but everytime I get only the dashboard home site, maybe something causes a redirect.
I tried to simulate the same http request, as my browser send it away. My question is: Is there a possiblity to send the same header data (Cookie, Session-ID etc.) directly as parameter to file_get_contents without manual serialization?
It's a common PHP question, the basic script would be:
$postdata = http_build_query(
array(
'var1' => 'some content',
'var2' => 'doh'
)
);
$opts = array('http' =>
array(
'method' => 'POST',
'header' => 'Content-type: application/x-www-form-urlencoded',
'content' => $postdata
)
);
$context = stream_context_create($opts);
$result = file_get_contents('http://example.com/submit.php', false, $context);
And in my case the code is:
$postdata = http_build_query(
array
(
'selected_products' => 'some content',
)
);
$opts = array('http' =>
array
(
'method' => 'POST',
'header' => "Content-type: application/x-www-form-urlencoded; charset=UTF-8\r\n".
"Cookie: __utma=".Mage::getModel('core/cookie')->get("__utma").";".
"__utmz=".Mage::getModel('core/cookie')->get("__utmz").
" __utmc=".Mage::getModel('core/cookie')->get("__utmc").';'.
"adminhtml=".Mage::getModel('core/cookie')->get("adminhtml")."\r\n".
"X-Requested-With: XMLHttpRequest\r\n".
"Connection: keep-alive\r\n".
"Accept: text/javascript, text/html, application/xml, text/xml, */*\r\n".
"User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:12.0) Gecko/20100101 Firefox/12.0",
'content' => $postdata
)
);
$context = stream_context_create($opts);
var_dump(file_get_contents($runStopAndRemoveProducts, false, $context ));
The result should be the same error message I'll get in the browser by calling the URL manually ("please select some products" as plain text), but the response is a full dashboard home page as html website.
I'm looking for a script like this. I want to make sure all parameters are set automatically without manual build the cookie string and the other ones :)
file_get_contents('http://example.com/submit.php', false, $_SESSION["Current_Header"]);
EDIT: I've found the mistake, two special get-Parameter (isAjax=1 and form_key = Mage::getSingleton('core/session', array('name' => 'adminhtml'))->getFormKey()) are required. In my case the form_key causes the error. But the ugly Cookie string is already there - still looking for a more pretty solution.
To me this looks like you are trying to write a hack for something that you can do more elegantly, the proper, fully documented way. Please have a look at the Magento API.
If you want to delete products (or do anything else):
http://www.magentocommerce.com/api/soap/catalog/catalogProduct/catalog_product.delete.html
You will get a proper response back to know if things have been successful. If there are things the API cannot do then you can extend/hack it if you wish.
To get started you will need an API user/pass and get up to speed with SOAP. The examples in the Magento documentation should suffice. Good luck!

cURL without cURL- problem

I wanted to copy files from a remote server, but it seems that the remote host is using session, and needs cookies.
well I used this method
after defining variables...
$url="http://example.com/stamp/stamp.jsp?tp=&arnumber=5255176&isnumber=5255174";
$nn = "\r\n";
$cookies="";
$request = GET . " " . str_replace ( " ", "%20", $url ) . " HTTP/1.1" . $nn . "Host: " . $host . $nn . "User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1.14) Gecko/20080404 Firefox/2.0.0.14" . $nn . "Accept: */*" . $nn . "Accept-Language: en-us;q=0.7,en;q=0.3" . $nn . "Accept-Charset: windows-1251,utf-8;q=0.7,*;q=0.7" . $nn . "Pragma: no-cache" . $nn . "Cache-Control: no-chache" . $nn . $proxyauthorization . $referer . $cookies . "Connection: Close";
$fp= socksopen($Proxy,$port, $errno, $errstr, 15 );
socket_set_timeout ( $fp, 120 );
fputs ( $fp, $request );
fflush ( $fp );
//read header
$i = 1;
do {
$header.= #fgets ( $fp, 128 );
$i++;
} while ( strpos ( $header, $nn . $nn ) === false );
echo $header;
fclose ($fp);
now I have the header with cookies that the url said :
HTTP/1.1 302 Moved Temporarily Content-length: 0 Content-type: text/html Server: Sun-ONE-Web-Server/6.1 Date: Mon, 28 Dec 2009 13:40:53 GMT Set-cookie: ERIGHTS=5YAaxxmNsMuTK87E1TCAohwDRuyqBaCgM-oehmg24bkzHplCtmgn7zMA==;path=/;domain=.example.org Set-cookie: WLSESSION=1528980108.20480.0000; expires=Tue, 29-Dec-2009 13:40:52 GMT; path=/ Location: http://example.com/stamp/stamp.jsp?tp=&arnumber=5255176&isnumber=5255174"&tag=1 Via: 1.1 proxy-server1 Proxy-agent: Sun-Java-System-Web-Proxy-Server/4.
then I did some sting code and built this in the code:
$cookies="cookie: ERIGHTS=5YAaxxmNsMuTK87E1TCAohwDRuyqBaCgM-oehmg24bkzHplCtmgn7zMA==,WLSESSION=1528980108.20480.0000";
re-requesting the url with same method mentioned above
and again i have got same header with another cookies
It seams that the remote website is treating me as a first-time visitor each time and sets new cookies gain
there is one thing, the file i am trying to copy is a .pdf file exactly
i checked that by my browser, the results:
say the URL is:
http://example.com/stamp/stamp.jsp?tp=&arnumber=5344171&isnumber=5344169
I checked the source code of the URL, it contains a redirection to another page that either is a javascript with iframe
source of the page (from my browser)
<frameset rows="65,35%">
<frame src="http://example.com/stamp/banner.jsp" frameborder="0" framespacing="0" framepadding="0" scrolling="no" />
<frame src="http://example.com/stampPDF/getPDF.jsp?tp=&arnumber=5255176&isnumber=5255174" frameborder="0" />
as you see when I click the URL, it redirects me to URL2
the URL2 is this:http://example.com/stampPDF/getPDF.jsp?tp=&arnumber=5255176&isnumber=5255174
the URL2 contains .pdf file I can easily copy(download).
but when i use my code mentioned above, $url="http://example.com/stamp/stamp.jsp?tp=&arnumber=5255176&isnumber=5255174"
it needs cookies to set with my request, when receive cookies and set and send cookies with my request it again replies a new cookie !!
what is wrong guys?
May be you should check your cookie-composing logic. Name-value pairs in a cookie header are supposed to be separated with ';' not with ',': http://msdn.microsoft.com/en-us/library/aa920098.aspx#wce50concookieheadersanchor2.
And (I'm sure you do this) I would double-check all the request headers with Fiddler, HttpAnalyzer or another similar tool.
Are you passing over http://example.com/stampPDF/getPDF.jsp?tp=&arnumber=5255176&isnumber=5255174 as the referer? The site may be checking that.

Categories