API token authentication issues in php - php

First of all I want to say that I'm not a native english (french) so that's why this could bring some mistakes sometimes.
So my problem is that I'm trying to use the API of a website, which documentation can be found at documentation
The problem is for requests which need authentication, every thing is fine for public requests.
So I tried the first request which is according to the website 'retrieve account balances' which is a signed get method (using a hmac256 payload).
Thing are getting harder since the documentation is saying that the payload has to be either recvWindow=5000×tamp=1540203005798 (with the weird cross before tamp) even if I think this is more a display problem or has we can find in the documentation at another line : recvWindow=5000&timestamp=my timestamp.
So this is the first problem because I don't know the which one to use in the payload. (but I've tried with both and it didn't work so ...).
Then I wrote a quick php script to retrieve my informations :
<?php
include('pwd.php');
$time = time()*1000;
$sign = hash_hmac('sha256', 'recvWindow=5000&timestamp='.$time, $private);
$opts = array(
'http'=>array(
'method'=>"GET",
'header'=> array("Authorization" => $public,
"Signature" => $sign
)
));
$context = stream_context_create($opts);
$fp = file_get_contents('https://trade.coss.io/c/api/v1/account/balances?
recvWindow=5000&timestamp='.$time, false, $context);
echo $fp;
?>
The first include juste includes my public key and my private key.
I run out of idea to find what is the problem with this script, because I tried with every payload with the cross without the cross with my timestamp with fixed timestamp but nothing work, I just get 500 error.
Any kind of help would be great.

I found the answer to my problem it came from the header which had a syntax mistake, instead of what I wrote the proper way is :
$opts = array(
'http'=>array(
'method'=>"GET",
'header'=> array("Authorization: ".$public,
"Signature: ".$sign
)
));

Related

Authenticate with Wordpress cookie through API from a subdomain

I want to access the current logged in Wordpress user in a separate Laravel installation.
Wordpress is running as website.com and I've got a subdomain with tool.website.com with the Laravel application (on another server but same domain).
I'm using the Native Wordpress API and created an authentication route.
The issue:
When I access the /authenticate route directly, the user ID is returned and works correctly. But when I access the route through tool.website.com false is returned..
Things I've got working:
I've created an API request which returns the user id in an API call:
add_action( 'rest_api_init', function () {
register_rest_route( '/authenticate', array(
'methods' => 'GET',
'callback' => 'authenticate',
) );
} );
The function looks like this:
$user_id = wp_validate_auth_cookie( $_COOKIE[LOGGED_IN_COOKIE], 'logged_in' );
The WP cookie is available on both the sub / main domain. I can see they are identical and toplevel.
define('COOKIE_DOMAIN', '.website.dev');
Things I've tried:
Using wp_get_current_user() to retrieve the user, this seems to need a nonce. I experimented hours and hours with the nonce approach on many different ways, but I could not get this to work (false or 0 was returned). I understand this is due to restrictions of using a nonce from outside of Wordpress.
Using the default native API approach to get the user, also needs the nonce.
Reading the https://developer.wordpress.org/rest-api/ manual, git repository & several articles / comments online.
Thinking about the OAuth approach, but I do not want users to login again as they are already logged in when they reach the tool.
Sending stuff like posts etc works without problems, so the API connection is not the problem.
I'm wondering if my approach is in the right direction. Hopefully someone can give me some guidance.
I found the following workaround:
- tool.website.com
Send the Cookies from tool.website.com to the API as post data.
$cookie_array = $_COOKIE;
// use key 'http' even if you send the request to https://...
$options = array(
'http' => array(
'header' => "Content-type: application/x-www-form-urlencoded\r\n",
'method' => 'POST',
'content' => http_build_query($cookie_array)
)
);
$context = stream_context_create($options);
$data = file_get_contents(self::BASE_URL . "authenticate", false, $context);
- website.com
Retrieve the cookie from Post data, and use the standard LOGGED_IN_COOKIE constant in Wordpress to select the correct one (this can be refactored to sending the correct cookie at once).
// We retrieve the cookie (which is sadly not available through the API call alone)
$the_cookie = $request->get_body_params();
// As the cookie lives at domain level, we can use the same Cookie key in the WP API and other subdomains of this domain
// The cookie key remains the same
$user_id = wp_validate_auth_cookie( $the_cookie[LOGGED_IN_COOKIE], 'logged_in' );
This solution seems steady; hopefully it will help someone. If there are other solutions, please add them in this topic; as I'm sure there must be different ways achieving this.

GET works but POST doesn't for silent login

We have 2 systems one in PHP and one in asp.net which currently require separate logins even though both use the same username/password information.
As a quick (and temporary) fix I thought I might be able to amend the PHP login page to pass the login details to the asp.net page behind the scenes so the user could be logged in automatically to both systems rather than having to enter their credentials again when navigating to a different page.
This works fine when I use a GET to pass the parameters but of course the GET parameters including the password get stored in the server log which is not a good idea.
So I would like to use POST instead, but I can't get it to work. I used the CURL-less method in How do I send a POST request with PHP? (code below) and it appears to work but the asp.net login process creates secure cookies and while they are stored if I GET the page they are not being stored when I POST to it instead.
$url = 'https://server.com/path';
$data = array('key1' => 'value1', 'key2' => 'value2');
// use key 'http' even if you send the request to https://...
$options = array(
'http' => array(
'header' => "Content-type: application/x-www-form-urlencoded\r\n",
'method' => 'POST',
'content' => http_build_query($data),
),
);
$context = stream_context_create($options);
$result = file_get_contents($url, false, $context);
var_dump($result);
I have tried something similar with CURL in the past so I know that CURL creates it's own browser context but I thought a straight POST request would work, however it seems to be behaving much the same as CURL.
Is there some way to get this to work or do I have a fundamental misunderstanding of how POST works? If so could somebody point me at a good explanation.

Windows Azure Authentication for Bing Search in PHP

I am trying to perform a Bing Search by using the Windows Azure Marketplace API, I have downloaded their guide and sample code. The code prepares a HTTPS request with basic authentication, however I am constantly getting the following error:
Warning: file_get_contents(https://api.datamarket.azure.com/Data.ashx/Bing/SearchWeb/Web?Query=%27washburn%27&Adult=%27Off%27&$top=50&$format=Atom): failed to open stream: Connection refused
The php code (from Microsoft's document):
$context = stream_context_create(array(
'http' => array(
'proxy' => 'tcp://127.0.0.1:8888',
'request_fulluri' => true,
'header' => "Authorization: Basic " . base64_encode($accountKey.":".$accountKey)
)
));
Does anyone know what is causing the error please? I have correctly set the $accountKey and I tested it in a browser. What puzzles me a little is 127.0.0.1:8888 and also base64_encode($accountKey.":".$accountKey) , how come you need the $accountKey both before and after the : while when using a browser you are supposed to leave the username blank and just input the account key into the password field?
I have solved it and here is what I have found for future people that would be doing the same thing:
I commented out the line where it says:
'proxy' => 'tcp://127.0.0.1:8888',
'request_fulluri' => true,
and also set base64_encode("ignored:".$accountKey) instead
Base on what I read on MSDN, the username part is said to be ignored, so it shouldn't matter what value it is. I was thinking perhaps the length or the special characters in the key screwed things up so I replaces it with ignored (or anything really).
That did the trick and I can parse the returned JSON data. Good luck!

php stream_context_create confusion

I know that this feature in php creates and returns a stream context with any options supplied in options preset. I also know that I can use it to do what I want which is to pass my username and password credentials...But I still don't quite get how to use this feature and what it exactly does the complicated words in the description are really confusing me....I have the code from the example but I don't know how I can use this feature to pass credentials to www.confluence.com (only I can access it since its on a apache server). Can someone please explain or give example of how I can use this to pass the credentials?
EDIT: Here is the overal summary, pretty short so dunno if you call it a summary....I am assigned an app to make.....there is about 10 different ways to do this. due to the limitations they have given me, I can only work with 1 way that I found...I am very frustrated because there is a much easier way to do this using google calendar but they refuse due to security reasons so I am stuck to confluence calendar.....In addition to that, to make this harder, confluence is hosted by external company and so I cannot even use get_contents to directly access the confluence calendar because it asks for login credentials....I am not a pro at this and one after another obstacles keep popping up to make my life harder and this is just bs...Ive spent hours and hours for the past 3 weeks finding solutions only to have it rejected...Ive finally got this get_contents thingy working but now login credentials is a pain in the butt and I have never dealt with this so I am trying my best but I have ABSOLUTELY NO IDEA what stream_context_create does OR how to even use it to pass my credentials...Confluence the site I am trying to access I can manually login using my logins but the code cannot....confluence is on an apache server so other people cannot access it....and I cannot share my login info as that is company's security issue...I am sorry if i made no sense but I am very frustrated and can find no solution and my mind is half dead from coding and reading
Believe me I have done much searching and googling....But Ive finally reached the point where I am blank stuck...
<?php
$opts = array(
'http'=>array(
'method'=>"GET",
'header'=>"Accept-language: en\r\n" .
"Cookie: foo=bar\r\n"
)
);
$context = stream_context_create($opts);
/* Sends an http request to www.example.com
with additional headers shown above */
$fp = fopen('http://www.example.com', 'r', false, $context);
fpassthru($fp);
fclose($fp);
?>
I found some additional code here similar to what I am doing but not quite sure what to do with this or how to modify it..
$data = array('account'=>'javier',
'password'=>'12345',
'submit'=>'SUBMIT');
$content = file_get_contents('http://localhost/misc/login.php', false, stream_context_create( array('http' => array('method' => 'POST', 'content' => http_build_query($data) ) ) ) );
$sFind = 'Logged in';
$search = strpos($content, $sFind);
echo $content;
if($search === false){
echo 'Invalid Account';
}
else {
echo 'Valid Account';
}
Another Idea I have is to use JavaScript to do the login...I dont know which is better but I am not allowed to download any libraries or such so suggestions are nice.
You are using the 'GET' method, it is uncommon for login information to be passed like this.
Are you sure the page you are requesting doesn't use POST?
Also personally when retrieving webpages, especially when sending POST or GET variables I prefer to use cURL.

Get Flickr Sets

Usual stuff, Googled forever, looked on here, no help. Yet.
What I want is to list the sets of photos I have on Flickr. Nice & simple, it would seem.
I want the 'title image' (the one used as the thumb for it on Flickr its self), the title and URL. Can't be that hard, can it?
The language of choice is PHP (5.1.6), or JS (jQuery if possible). Both are good.
Using flickr.photos.search method of the API with your user_id does not work ?
For PHP, you have a PEAR-based package here and another library at http://phpflickr.com/. Should be enough to get through it.
EDIT :
For minimal implementation you should use stream_context_create() with HTTP headers, use fopen() with this context and build a XMLRPC request by hand as a text variable that you will send. Answer from the socket will be your data
For the API, use flickr.photosets.getList
CODE EXAMPLE (you need a valid api key for flickr)
<?php
$apiKey = '';
$userID = '';
$url = 'http://api.flickr.com/services/rest/?method=flickr.photosets.getList&api_key='
.$apiKey.'&user_id='.$userID.'&format=json';
$options = Array('http' => Array('method' => 'GET'));
$context = stream_context_create($options);
$response = file_get_contents($url, false, $context);
$object = json_decode($response);
see also http://framework.zend.com/manual/en/zend.service.flickr.html for a nice tidy wrapper

Categories