how to set "REFERER" in Zend_Http_Client? - php

Hi
I am using Zend_Http_Client with adapter Zend_Http_Client_Adapter_Curl , I tried setting REFERER using
$client = new Zend_Http_Client('http://www.example.com',array('adapter'=>'Zend_Http_Client_Adapter_Curl');
$client->getAdapter()->setCurlOption('CURLOPT_REFERER','http://www.google.com');
$client->request('POST');
echo $client->getLastRequest();
In my Request I see all kinds of header getting set except REFERER header ??
It can be done using $client->setHeaders('Referer',$url); also but I am looking for a better way.
Thanks.

What is interesting about your code is that I just tried to run it and a got errors. So I could not test it. For this reason, I tried another way:
$adapter = new Zend_Http_Client_Adapter_Curl();
$adapter->setCurlOption(CURLOPT_REFERER, 'http://www.google.com');
$client = new Zend_Http_Client('http://www.example.com');
$client->setAdapter($adapter);
$client->request('POST');
var_dump($client->getLastRequest());
The above code results in:
string 'GET /domains/example/ HTTP/1.1
Accept: */*
Referer: http://www.google.com <-- THE REFERER
Host: www.iana.org
Connection: close
Accept-encoding: gzip, deflate
User-Agent: Zend_Http_Client
' (length=180)
So in this case it seems Referer header is set correctly.
EDIT:
On the OP's request I also tested:
$adapter = new Zend_Http_Client_Adapter_Curl();
$client = new Zend_Http_Client('http://www.example.com');
$client->setAdapter($adapter);
$client->getAdapter()->setCurlOption(CURLOPT_REFERER, 'http://www.google.com');
// This line below results in error:
// $client->getAdapter()->setCurlOption('referer', 'http://www.google.com');
$client->request('POST');
var_dump($client->getLastRequest());
This also works as before.

Related

SOAP XML Request with Basic Authentication in PHP

I am trying to setup a SOAP request in PHP using HTTP basic Authentication. For some reason I keep getting, HTTP/1.1 401 Unauthorized error.
This is an example of the request I'm trying to create:
POST https://url/someurl/soap HTTP/1.1
Accept-Encoding: gzip,deflate
Content-Type: text/xml;charset=UTF-8
SOAPAction: "SomeSoapAction"
User-Agent: SomeUser Client-HttpClient/3.1
Content-Length: 1503
Authorization: Basic dGsomebasicreyteryheyp0ZXN0ZXI=
Host: somehost.com
This is a snippet of my code:
ini_set('display_errors',1);
ini_set("soap.wsdl_cache_enabled", "0");
error_reporting(E_ALL);
$wsdl = "urltosomewsdlfile.wsdl";
$url = "somerl";
$username = "username";
$password = "password";
$encodedstuff = base64_encode("{$username}:{$password}");
$client = new SoapClient($wsdl, array('exceptions' => true,'trace' => true,'login' => 'somelogin', 'password' => 'somepw'));
$header = new SoapHeader($url, 'Authorization: Basic', $encodedstuff);
$client->__setSoapHeaders($header);
try {
$result = $client->SomeSoapAction();
} catch (SoapFault $soapFault) {
var_dump($soapFault);
echo "<br />Request :<br />", htmlentities($client->__getLastRequest()), "<br />";
echo "<br />Response :<br />", htmlentities($client->__getLastResponse()), "<br />";
}
If I take the username and password out of the new SoapClient section it throws up Uncaught SoapFault exception: [WSDL] SOAP-ERROR: Parsing WSDL: Couldn't load from...
If I put in the base64 encoded variable to the new SoapClient section instead of the username/pw it throws the same Parsing error as above:
$client = new SoapClient($wsdl, array( 'authentication' => "Basic $encodedstuff", 'exceptions' => true,'trace' => true,));
The username and password work when loading the URL directly.
Can anyone point me in the right direction? Thanks for any help.
Update 12/18/18: I've been trying this as a new method suggested, but still receive the same 401 error message:
$opts = array( 'http'=>array( 'method'=>"POST", 'header' => "Authorization: Basic " . base64_encode("{$user}:{$pw}") ) );
$context = stream_context_create($opts);
$client = new SoapClient($wsdl, array('stream_context' => $context,'exceptions' => true,'trace' => true,));
$header = new SoapHeader($url, 'Authorization: Basic', $encodedstuff);
$client->__setSoapHeaders($header);
Update 15/01/19:
I'm still having issues with this.
Using SOAPUI I can make a successful request and gain authentication. I can't see what the difference is between the SOAPUI request and my own PHP request.
I've noticed that the request header created by my PHP code alters the POST and Host endpoint URLs. The first part of the POST URL has the domain removed and the Host also has the first section of the URL removed.
SOAPUI request header (correct returns 200):
POST https://test-example.com/file/SOAP HTTP/1.1
Host: test-example.com
PHP request header (returns a 401):
POST /file/SOAP HTTP/1.1
Host: example.com
This seems to be causing the problem as it looks as if I'm pointing to the wrong endpoint. Does anyone have any advice on what might be wrong with my PHP code to break this request? Thanks.

Basic auth with php soap

I'm trying to connect to a soap server that use a Basic Authentication with PHP7
With this example, the login and password are not send in the header.
Do I miss something ?
Code:
$options = [];
$options['login'] = $authentication->getLogin();
$options['password'] = $authentication->getPassword();
$options['authentication'] = SOAP_AUTHENTICATION_BASIC;
$client = new SoapClient($wsdl, $options);
$client->__soapCall($functionName, $arguments);
Header send:
POST /V4/services/ServerAPI HTTP/1.1 Host:
serverurl.com Connection: Keep-Alive User-Agent: PHP
version: PHP SDK 4.52.1 Content-Type: application/soap+xml;
charset=utf-8; action="test" Content-Length: 6904
Normally i should see something like
Basic authentication: mybase64
$authentication->getLogin() return an integer. Cast with string solve the issue.
$options['login'] = (string) $authentication->getLogin();

Soap Header with Authorization Basic in native PHP

i need to connect to TeraData SOAP API which now demands a Authorization Basic Header to be sent with the login credentials. I do not know how to adress the problem. I got the access working in SoapUI when adding Basic Authorization Header - please can anyone help me to get the code straight:
Here's the Header SoapUI sends and the response is good:
POST http://example.com/api/soap/v6 HTTP/1.1
Accept-Encoding: gzip,deflate
Content-Type: text/xml;charset=UTF-8
SOAPAction: ""
Content-Length: 302
Host: example.com
Connection: Keep-Alive
User-Agent: Apache-HttpClient/4.1.1 (java 1.5)
Authorization: Basic [user&pass-base64-encoded]
Here's how i am trying to set up my SoapClient:
$namespace = "http://ecircle.com/developer/ecmapi";
$wsdl = "https://sslh.teradatadmc.com/teradata/api/soap/v6?wsdl";
$client = new SoapClient($wsdl, array("trace" => 1, "exceptions" => 0));
$login = 'xxx';
$password = 'yyy';
$header = new SoapHeader($namespace, 'Authorization: Basic',
base64_encode("$login:$password"));
$client->__setSoapHeaders($header);
it's not accepted and i just get an HTTP/1.1 401 Unauthorized Error
The stacktrace shows me the header that i sent - the Authorization part is missing there.
public '__last_request_headers' => string 'POST /api/soap/v6 HTTP/1.1
Host: example.com
Connection: Keep-Alive
User-Agent: PHP-SOAP/5.5.12
Content-Type: text/xml; charset=utf-8
SOAPAction: ""
Content-Length: 584
man i was so stupid:
$client = new SoapClient($wsdl, array("trace" => 1, "exceptions" => 0,
"login" => $login, "password" => $password) );
For HTTP authentication, the login and password options can be used to supply credentials.
That's because you should encode your login credentials this way:
base64_encode("$login:$password")
instead of:
base64_encode($login) . ':' . base64_encode($password)

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();
}
}

How do I use Yelp's API in ZF2?

I'm trying to connect to Yelp's API, currently using ZF2 and ZendOAuth. I don't know why I'm getting a 404. Here is the raw request and response headers.
POST /v2/search?term=tacos&location=sf HTTP/1.1
Host: api.yelp.com
Connection: close
Accept-Encoding: gzip, deflate
User-Agent: Zend\Http\Client
Content-Type: application/x-www-form-urlencoded
Authorization: OAuth realm="",oauth_consumer_key="<key>",oauth_nonce="<nonce>",oauth_signature_method="HMAC-SHA1",oauth_timestamp="1387401249",oauth_version="1.0",oauth_token="<token>",oauth_signature="<signature>"
HTTP/1.1 404 Not Found
Date: Wed, 18 Dec 2013 21:14:09 GMT
Server: Apache
X-Node: web41, api_com
Content-Length: 8308
Vary: User-Agent
Connection: close
Content-Type: text/html; charset=UTF-8
X-Mode: rw
X-Proxied: lb1
Does that request look like it should connect somewhere?
Here's some code.
$accessToken = new \ZendOAuth\Token\Access();
$accessToken->setToken('<token>');
$accessToken->setTokenSecret('<secret>');
$host = 'http://' . $_SERVER['HTTP_HOST'];
$config = array(
'consumerKey'=>'<key>',
'consumerSecret'=>'<secret>',
);
$client = $accessToken->getHttpClient($config);
$client->setUri('http://api.yelp.com/v2/search?term=tacos&location=sf');
$client->setMethod('POST');
$adapter = new \Zend\Http\Client\Adapter\Socket();
$client->setAdapter($adapter);
$response = $client->send();
$result = $response->getBody();
All the examples of OAuth I've seen get the access token with a request token, but Yelp already gave me the token and secret, so I'm trying to construct it manually.
Update:
Changing
$client->setMethod('POST');
to
$client->setMethod('GET');
is the first step, but the parameters can't be added manually to the URL, they have to be added with setParameterGet();. So here's my updated working code.
$accessToken = new \ZendOAuth\Token\Access();
$accessToken->setToken('<token>');
$accessToken->setTokenSecret('<secret>');
$host = 'http://' . $_SERVER['HTTP_HOST'];
$config = array(
'consumerKey'=>'<key>',
'consumerSecret'=>'<secret>',
);
$client = $accessToken->getHttpClient($config);
$client->setUri('http://api.yelp.com/v2/search');
$client->setMethod('GET');
$params = array('term'=>'tacos', 'location'=>'sf');
$client->setParameterGet($params);
$adapter = new \Zend\Http\Client\Adapter\Socket();
$client->setAdapter($adapter);
$response = $client->send();
$result = $response->getBody();
That api requires GET method. So change:
$client->setMethod('POST');
To:
$client->setMethod('GET');
And try again )

Categories