The web service I'm trying to consume has such a WSDL file: http://dgpysws.teias.gov.tr/dgpys/services/EVDServis?wsdl
I'm trying to consume "setIkiliAnlasma" service, however accessing that service requires authentication. I have my credentials and when I make a SOAP call to login service it authenticates my credentials.
And as expected, when I call "setIkiliAnlasma" service I get an Authorization error. What is the method to combine authorization supplied by login call with the main service I need to consume?
By the way the programming language I'm usign is PHP and the native SoapClient functions: http://www.php.net/manual/en/class.soapclient.php
Here is an example of using the SOAPClient in PHP with authentication - you just need to adapt it to the WSDL you are using ->
// Setting "trace" will allow us to view the request that we are making, after we have made it.
$objClient = new SoapClient("http://www.somewhere.com/wsdls/some.wsdl", array('trace' => true));
// These parameters satisfy this specific remote call.
$arrParameters_Login = array('username' => 'username', 'password' => 'password');
// Invoke the remote call "login()".
$objLogin = $objClient->login($arrParameters_Login);
// Grab session ID that this remote call will provide.
$strSessionID = $objLogin->loginReturn->sessionId;
You will then need to use the sessionid / session code that is sent to you in the login response - maybe in a header - its specific to each WSDL.
try to use this way to authenticate when calling the soap client url :
http://username:password#domain.com/
Related
I am trying to send a SOAP request to a client's API endpoint. I am not at all familiar with SOAP, so having quite a difficult time getting this to work.
From the client's documentation
The requested ticket can be used to call all the API web methods subsequently.
public string RequestTicket(
string username,
string password
);
URL
https://www.clientsurl.net/api/v01_00/APIService.asmx?wsdl
Parameters
string username
string password
I am able to create the WSDL
$client = new Client('https://www.clientsurl.ca/api/v01_00/APIService.asmx?wsdl', ['soap_version' => SOAP_1_1]);
but not sure how to send the parameters through
$params = [
'username' => 'myusername'
'password' => 'mypassword'
];
I am also not sure what the relevance of RequestTicket is. Am I supposed to add it to the url?
The answer is probably very simple, but after tons of searching I couldn't find anything. Please help.
I have write a method to send a request
protected function soapRequest(string $method, array $arguments)
{
try {
$client = new \Zend\Soap\Client($this->getWsdl(),
[
'soap_version' => SOAP_1_1,
'cache_wsdl' => WSDL_CACHE_NONE
]);
$result = $client->{$method}($arguments);
return $result->return;
} catch (\SoapFault $s) {
...
} catch (\Exception $e) {
...
}
}
You must have a Soap method to send yours parameters.
If you don't know the method name, I advise you to run SoapUI application, very useful for debugging soap requests.
A SOAP service has a set of operations that you can call over the network. These operations can also have parameters. Basically, it's just like calling a method with parameters in code just that the invocation happens over the network with the method name and parameters being marshaled into an XML that respects the rules of the SOAP protocol.
To call the SOAP service, you can either make a HTTP request of type POST to the service's endpoint (i.e. https://www.clientsurl.ca/api/v01_00/APIService.asmx) or you can use a SOAP client. A SOAP client is some code that you can generate from the WSDL of the SOAP web service, or is some code that can dynamically read the WSDL and provide you some ways to invoke the operations described there. As opposed to making a POST HTTP request, the client takes care of these details for you and allows you to make the call over the network just like you call a local method in your code.
To call an operation of the SOAP service in your client code you have to invoke a method with parameters. The name of the method and its parameters (what names and what types) are described by the WSDL of the service.
With that being said, I'll add some details about what you posted in your question.
The requested ticket can be used to call all the API web methods subsequently.
Some service operations can require authentication in order to be be allowed to invoke them. Just like you need a username and password to access protected sections of a website for example. For a SOAP web service, his can happen in a few ways, the most common two being:
you send the username and password with each call to the web service (somehow; can be as SOAP headers, as HTTP headers with BASIC Authentication, etc).
the service exposes a method that you have to call with username and password just like point 1), but then returns an access token of some sort that you then need to provide to the rest of the web service's operations. This is just like a Login page on a website where you authenticate with username and password and then you get back a SessionID that you can use on all other requests until you decide to log out.
It seems that your service uses the second approach, and RequestTicket seems to be the operation that you need to call in order to be able to call the rest of the operations after that.
I am able to create the WSDL
You do not create the WSDL, the WSDL already exists for the web service. Also make sure you do not make a confusion between the SOAP web service and its WSDL. The code you show just creates a SOAP client from the WSDL (what I described above) to allow you to invoke operations on it.
I am also not sure what the relevance of RequestTicket is. Am I supposed to add it to the url?
Most likely RequestTicket is an operation of the web service. You should look inside the WSDL to see if it's described there. The WSDL is a little tough to swallow if you are not familiar with how it works, so your best bet is to use a tool like SoapUI to feed it the web service WSDL and have SoapUI generate sample requests for the web service. You can then also use SoapUI to test the web service to make sure you understand how it works before you try to replicate the same calls with your PHP code.
I'm using Hybridauth 3 in my PHP app to make some periodical tweets on behalf of my account.
The app has all possible permissions. I'm giving it all permissions when it asks for them on the first auth step.
After that Twitter redirects me to the specified callback URL and there I'm getting a pair of access_token and access_token_secret.
But when I'm trying to make a tweet using these tokens - it gives me:
{"errors":[{"code":220,"message":"Your credentials do not allow access to this resource."}]}
Here's how I'm trying to make a tweet:
$config = [
'authentication_parameters' => [
//Location where to redirect users once they authenticate
'callback' => 'https://mysite/twittercallback/',
//Twitter application credentials
'keys' => [
'key' => 'xxx',
'secret' => 'yyy'
],
'authorize' => true
]
];
$adapter = new Hybridauth\Provider\Twitter($config['authentication_parameters']);
//Attempt to authenticate the user
$adapter->setAccessToken(/*tokens I've got from getAccessToken() on /twittercallback/*/);
if(! $adapter->isConnected()) {
// never goes here, so adapter is connected
return null;
}
try{
$response = $adapter->setUserStatus('Hello world!');
}
catch (\Exception $e) {
// here I've got the error
echo $e->getMessage();
return;
}
Tried to recreate tokens and key\secret pairs and passed auth process for the app many times, including entering password for my Twitter account (as suggested in some posts on stackoverflow) but still have this error.
P.S. According to this, Hybridauth has fixed the issue in the recent release.
It looks like you are using application authentication as opposed to user authentication. In order to post a tweet, you must authenticate as a user. Also, make sure your Twitter app has read/write privileges.
After comparing headers of outgoing requests from my server with the ones required by Twitter, I've noticed that Hybris doesn't add very important part of the header: oauth_token. At least it's not doing this in the code for Twitter adapter and for the scenario when you apply access token with setAccessToken(). It's just storing tokens in the inner storage but not initializing corresponding class member called consumerToken in OAuth1 class.
So to initialize the consumer token properly I've overridden the apiRequest method for Twitter class (before it used the defalut parent implementation) and added a small condition, so when consumer token is empty before the request - we need to try to init it.
public function apiRequest($url, $method = 'GET', $parameters = [], $headers = [])
{
if(empty($this->consumerToken)) {
$this->initialize();
}
return parent::apiRequest($url, $method, $parameters, $headers);
}
I'm not sure that I've fixed it the best way, but as long as it's working - that's fine.
For your info setAccessToken was fixed in v3.0.0-beta.2 (see PR https://github.com/hybridauth/hybridauth/pull/880)
I faced the same error when implementing a sample app in clojure and the following resource was a huge help to sort out my confusion about application-only auth vs user authentication: https://developer.twitter.com/en/docs/basics/authentication/overview/oauth
Context: Laravel 5. Guzzle ~5.2. PHP 5.4. I'm building a class to interact with an external API. I'm providing this class with a Guzzle client using a Service Provider, to avoid instantiating the client within a method.
I want to cache the results. If the user is asking for something that is found in the cache, return it instead of performing a request to said API.
Problem: If I build up a Guzzle client and don't perform a request, the application crashes. Not even a stack trace from PHP. Actually, if I'm using Laravel's artisan serve, a Windows error message shows up saying, PHP CLI has stopped working.
For now, I'm passing the Guzzle client to the method on my class, every single time I call it.
Is there a way to just instantiate the Guzzle client without sending a request? What other route would you choose to achieve this? Is that intended behaviour?
tl;dr RTM
Longer version (from the docs):
Creating Requests
You can create a request without sending it. This is useful for building up requests over time or sending requests in concurrently.
$request = $client->createRequest('GET', 'http://httpbin.org', [
'headers' => ['X-Foo' => 'Bar']
]);
// Modify the request as needed
$request->setHeader('Baz', 'bar');
After creating a request, you can send it with the client’s send() method.
$response = $client->send($request);
from here:
http://docs.guzzlephp.org/en/stable/quickstart.html#making-a-request
use GuzzleHttp\Psr7\Request;
$client = new Client([
// Base URI is used with relative requests
'base_uri' => 'http://httpbin.org',
// You can set any number of default request options.
'timeout' => 2.0,
]);
$request = new Request('PUT', 'http://httpbin.org/put');
$response = $client->send($request, ['timeout' => 2]);
I received a manual to internal SOAP interface of my partner. It says:
MyPARTNER web services are provided in the form of a SOAP interface. The service is available in this URL: https://justsomeurl.com:435/soap
then some bla bla about authorization etc. and then a part about Accessible Methods:
pull()
The PULL method is used for pulling data from the database. The method
receives a unique data based parameter under an internal name
requestXML. This parameter contains data in a structured XML format.
String pull(String requestXML)
The XML contains data required to make the request, and the response
data is sent back.
then some other methods, error codes, it's not important here...
The problem is that I'm totally unexperienced in SOAP so I don't know how to use this interface via PHP. I've tried to find some examples, tutorials and I am now little bit more informed about SOAP and its functionality but still haven't found any advice about how to use interface like this...
thanx for any help
Php comes with PHP SOAP libraries, that usually are included and enabled after a common php installation.
Yuo are asked to biuld the client part of the webservice pattern. Your partner should provide you the .wsdl of the web service. The wsdl describes the avialble method, the parameters they need and what they return.
Tipically parameters and return values are array structures
This could be a skeleton for your code:
//build a client for the service
$client = new SoapClient("partner.wsdl");
//$client is now a sort of object where you can call functions
//prepare the xml parameter
$requestXML = array("parameter" => "<xml>Hello</xml>");
//call the pull function this is like
$result = $client->__soapCall("pull", $requestXML );
//print the value returned by the web service
print_r($result);
Here follows a non-wsdl example
First the location paramater is the address the SOAP request will be sent to.
The uri parameter is the target namespace of the SOAP service. This is related to xml namespaces.
A sample code for you could be:
//for URI specification you should watch your partners documentation. maybe also a fake uri (like mine) could work
//build a client for the service
$client = new SoapClient(null, array(
'location' =>
"https://justsomeurl.com:435/soap",
'uri' => "urn:WebServices",
'trace' => 1 ));
// Once built a non-wsdl web service works as a wsdl one
//$client is now a sort of object where you can call functions
//prepare the xml parameter
$requestXML = array("parameter" => "<xml>Hello</xml>");
//call the pull function this is like
$result = $client->__soapCall("pull", $requestXML );
//print the value returned by the web service
print_r($result);
Here a useful link: http://www.herongyang.com/PHP/SOAP-Use-SOAP-Extension-in-non-WSDL-Mode.html
I have this call to a Web Service that is developed with ASP:
$endpoint = Zend_Registry::get('config')->endpoint->services->myService;
$client = new Zend_Rest_Client($endpoint);
$client->userId($adminUserId);
$client->otherIds($otherIds);
$result = $client->get();
But when I try to call the service the parameter 'otherIds' is not been taken by the WS.
That is because the first called function apparently (as I grok from the source code) is chosen for the "method" parameter. The Zend REST server seems to take this format. I suggest for other servers to feed a dummy method to the client, so the first call should be
$client->Dummy();
After that, the arguments are set.