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();
Related
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.
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)
I have an api and a client that I'm developing, both in laravel and I get that error 18 when I try to connect to the api using guzzle.
In my api controller I have this:
public function index()
{
$users = User::orderBy('username', 'asc');
return Response::json(array(
'error' => false,
'users' => $users->get()->toArray()),
200
);
}
And if I do curl --user admin#admin.com:password http://myapi.api/api/v1/users
I get the info that I need correctly on my console:
{"error":false,"users":[{"id":"1","firstname":"","lastname":"","username":"admin#admin.com","created_at":"2014-10-17 15:35:10","updated_at":"2014-10-17 15:35:10","client_id":"0","enterprise_id":"0","usertype_id":"0"},{"id":"2","firstname":"","lastname":"","username":"seconduser","created_at":"2014-10-17 15:35:10","updated_at":"2014-10-17 15:35:10","client_id":"0","enterprise_id":"0","usertype_id":"0"}]}
The url even works in the browser (I get a popup for authentication and after it I get the same input on the browser). So it's only failing via guzzle.
Now on my client I have Guzzle installed and I'm trying this:
$client = new GuzzleHttp\Client();
$user='admin#admin.com';
$pass='password';
$res = $client->get('http://myapi.api/api/v1/users', array(
'auth' => array('admin#admin.com', 'password')
));
$users=$res->json();
$users=$users['users'];
And I get the error:
[curl] (#18) See http://curl.haxx.se/libcurl/c/libcurl-errors.html for an explanation of cURL errors [url] http://myapi.api/api/v1/users
What am I doing wrong?
EDIT: Using -v in the command I get:
$ curl -v --user admin#admin.com:password http://myapi.api/api/v1/users
* Hostname was NOT found in DNS cache
* Trying 127.0.0.1...
* Connected to myapi.api (127.0.0.1) port 80 (#0)
* Server auth using Basic with user 'admin#admin.com'
> GET /api/v1/users HTTP/1.1
> Authorization: Basic YWRtaW5AYWRtaW4uY29tOnBhc3N3b3Jk
> User-Agent: curl/7.37.1
> Host: myapi.api
> Accept: */*
>
< HTTP/1.1 200 OK
< Date: Mon, 20 Oct 2014 13:08:56 GMT
* Server Apache/2.2.29 (Unix) mod_fastcgi/2.4.6 mod_wsgi/3.4 Python/2.7.8 PHP/5.5.17 mod_ssl/2.2.29 OpenSSL/0.9.8za DAV/2 mod_perl/2.0.8 Perl/v5.20.0 is not blacklisted
< Server: Apache/2.2.29 (Unix) mod_fastcgi/2.4.6 mod_wsgi/3.4 Python/2.7.8 PHP/5.5.17 mod_ssl/2.2.29 OpenSSL/0.9.8za DAV/2 mod_perl/2.0.8 Perl/v5.20.0
< X-Powered-By: PHP/5.5.17
< Cache-Control: no-cache
< Set-Cookie: laravel_session=eyJpdiI6IjRPMk9TT0ZnZklTMG1uWlFDancyMWc9PSIsInZhbHVlIjoic1V1RjA5aVBJdFNLM0JLclNROEE1a0dCeHNEMWhVNFVReTlUOHdidE44WEJzRnB4WFkxdWo0V0ozcXFVSW9LYzZiZzZSSlFCNXNTTjl2Mzh4TlFtTUE9PSIsIm1hYyI6IjhlYzY0YjFkNTQzNjk5ZGMxNDk3YmY4ZjU4YTYzYzM4YzgxZjg1MzlhMWUxNWVjYWE4ZThlMmU0N2RjNWFkZGMifQ%3D%3D; expires=Mon, 20-Oct-2014 15:08:57 GMT; Max-Age=7200; path=/; httponly
< Transfer-Encoding: chunked
< Content-Type: application/json
<
* Connection #0 to host myapi.api left intact
{"error":false,"users":[{"id":"1","firstname":"","lastname":"","username":"admin#admin.com","created_at":"2014-10-17 15:35:10","updated_at":"2014-10-17 15:35:10","client_id":"0","enterprise_id":"0","usertype_id":"0"},{"id":"2","firstname":"","lastname":"","username":"seconduser","created_at":"2014-10-17 15:35:10","updated_at":"2014-10-17 15:35:10","client_id":"0","enterprise_id":"0","usertype_id":"0"}
EDIT: This question is probably too specific and even though I haven't found a solution and have gone a different way with this project because specifications have changed I will leave it here in case it can help someone.
My guess on the answer is as André Daniel suggests in a comment, that the authentication is breaking something and guzzle isn't giving me my original json thus creating the error.
On your question you said this URL works via the command line:
http://myapi.api/api/v1/users/1
But you are calling this URL via guzzle
http://myapi.api/api/v1/users
So are you sure the route you are trying to call via guzzle works via the command line?
I finally changed the approach as we needed a different authentication method, so this question is no longer relevant to my case.
I know this is pretty old, but here's what I got to work with Guzzle:
$client = new GuzzleHttp\Client();
$user = 'admin#admin.com';
$pass = 'password';
$res = $client->get('http://myapi.api/api/v1/users', [
'headers' => [
'Authorization' => 'Basic ' . base64_encode($user . ":" . $pass),
],
]);
$users = $res->json();
$users = $users['users'];
You could even store the authorization data on the Guzzle instance, like this:
$client = new GuzzleHttp\Client([
'headers' => [
'Authorization' => 'Basic ' . base64_encode($user . ":" . $pass),
],
]);
$user='admin#admin.com';
$pass='password';
$res = $client->get('http://myapi.api/api/v1/users');
$users = $res->json();
$users = $users['users'];
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 )
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.