Curl request not hitting apex rest webservice - php

I am trying to hit apex rest webservice from php using curl.I am getting the access token but my request not hitting the webservice as there are no logs generated from the salesforce side.But tested same request from postman and its working as required.
Previously i was getting Http error code 307.Now i am not recieving any error code.
$rAuth = json_decode(file_get_contents('https://dare.net/wpsf_auth.php/'));
$accessToken = $rAuth->access_token;
$url = 'https://dev2193--tfdev.cs47.my.salesforce.com/services/apexrest/wordpress/registration';
$ch = curl_init($url);
$jsonDataEncoded = json_encode($ret_res);
curl_setopt($ch, CURLOPT_POST, TRUE);
curl_setopt($ch, CURLOPT_POSTFIELDS, $jsonDataEncoded);
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: application/json','Authorization: Bearer '.$accessToken));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
$result = json_decode(curl_exec($ch));
And code generated by POSTMAN:
POST /services/apexrest/wordpress/registration HTTP/1.1
Host: dev2193--tfdev.cs47.my.salesforce.com
Authorization: Bearer ***********************************************
Content-Type: application/json
Cache-Control: no-cache
Postman-Token: 3f12eef1-700d-83ad-f1bf-ef3ad6c266f5

Your Salesforce server is located on a different domain: https://dev2193--tfdev.my.salesforce.com/
If you take a look at the JSON you get from https://dare.net/wpsf_auth.php, you'll see that "instance_url" attribute is pointing to a different domain.
Also, HTTP code 307 is a temporary redirect, meaning you should look at a different URL.

Related

Keycloak fails to authorize client from local php server, but return ok when using postman

I've setup local php server and wanted to get authorization token from keycloak.
I've send request like this:
$url = "http://docker:10040/auth/realms/myrealm/protocol/openid-connect/token"
$data = "client_id=postman&username=admin&password=12345&grant_type=password"
$headers = array('Content-Type: application/x-www-form-urlencoded');
curl_setopt($curl, CURLOPT_POST, 1);
curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
if ($data)
curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
curl_setopt($curl, CURLOPT_URL, $url);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($curl, CURLOPT_VERBOSE, 1);
$result = curl_exec($curl);
but this returns to me:
{"error":"unauthorized_client","error_description":"Client secret not provided in request"}
Now, this would obviously be the case of "you don't have such client", right? Except when I do send "basically" the same request using postman:
POST /auth/realms/myrealm/protocol/openid-connect/token? HTTP/1.1
Host: docker:10040
Content-Type: application/x-www-form-urlencoded
cache-control: no-cache
Postman-Token: c08c2144-4ea0-45ad-ab16-150db7768825
last line is body, but it's not readable so let's rephrase it:
grant_type:password
username:admin
password:12345
client_id:postman
So as you see, basically same. Except maybe postman token.
Result of postman is correct answer that does include access_token:
{
"access_token": "eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICIxWjZ0SXNXa2JLSUNkSG96eWJHT1QybU90S1p1T3RiMU9lNWVRTlZzLW5ZIn0.eyJqdGkiOiI0OWE2MmE4Ny1lMjc2LTRjMjctODA5YS1jMTUzMWViNjYzOWQiLCJleHAiOjE1NTI0MDE1NjMsIm5iZiI6MCwiaWF0IjoxNTUyNDAxMjYzLCJpc3MiOiJodHRwOi8vZG9ja2VyOjEwMDQwL2F1dGgvcmVhbG1zLzFzcGlubWlsbGlvbmFpcmUiLCJhdWQiOiJwb3N0bWFuIiwic3ViIjoiMjFlMjc5MmEtNGQ1NS00YTVjLTlmNDctNDcxMDA5ZTEzNmFiIiwidHlwIjoiQmVhcmVyIiwiYXpwIjoicG9zdG1hbiIsImF1dGhfdGltZSI6MCwic2Vzc2lvbl9zdGF0ZSI6ImU0MjY4YjQ3LWQzZjctNDQxMS1iYmY3LWM4MzE5OTUwZWE2OSIsImFjciI6IjEiLCJjbGllbnRfc2Vzc2lvbiI6IjFmMzhkYmE5LWRhYWMtNGUyOC1hODdjLTI4MDcyN2YzYzhjNSIsImFsbG93ZWQtb3JpZ2lucyI6W10sInJlYWxtX2FjY2VzcyI6eyJyb2xlcyI6WyJyb2xlX2FkbWluIiwicm9sZV92aWV3X3VzZXJzIiwicm9sZV9wYXJ0bmVyIiwidW1hX2F1dGhvcml6YXRpb24iLCJyb2xlX3BhcnRuZXJfYWRtaW5pc3RyYXRvciJdfSwicmVzb3VyY2VfYWNjZXNzIjp7InJlYWxtLW1hbmFnZW1lbnQiOnsicm9sZXMiOlsidmlldy11c2VycyJdfSwicmVzb3VyY2Utc2VydmVyIjp7InJvbGVzIjpbInJvbGVfYWRtaW4iLCJyb2xlX3BhcnRuZXIiLCJyb2xlX3BhcnRuZXJfYWRtaW5pc3RyYXRvciJdfSwiYWNjb3VudCI6eyJyb2xlcyI6WyJtYW5hZ2UtYWNjb3VudCIsInZpZXctcHJvZmlsZSJdfX0sIm5hbWUiOiIiLCJwcmVmZXJyZWRfdXNlcm5hbWUiOiJhZG1pbiJ9.Ojw34yZkNmeTBvD7M1OTLv5PRnPcNO7nxf5d_w8yh_zuGTXCwPEyKm1blfpBDYkrKtjbwnamwWWZeBKYzLCUwebnE5rrEDG13fKC3iTdqkh5tEYMRhn8C8LAGBPy6uVhWJyL2X9CCbNQNNTiBUD3Ida6EK1K0rreoSpWInHgEktBumpleFdznCUHoZe6-xina5S4yC1TtZOWtSl4nrBgrn720uqmg-lN6_HacV6YnldYmtJWr_ay7EvmTAc4KLh5XU6YyulcXrq7Z921Zqupe3VJRhhFNssWYqT7c_bIGao5HYTgcmOnRsp_iGuT_6ku2LFEKXrLxmVJDaM9ok_3lA",
"expires_in": 300,
"refresh_expires_in": 1800,
"refresh_token": "eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICIxWjZ0SXNXa2JLSUNkSG96eWJHT1QybU90S1p1T3RiMU9lNWVRTlZzLW5ZIn0.eyJqdGkiOiIyOTJhMTY4NC1jZjk1LTRkYmMtYjdhNy1iM2RhZTZlY2NlODciLCJleHAiOjE1NTI0MDMwNjMsIm5iZiI6MCwiaWF0IjoxNTUyNDAxMjYzLCJpc3MiOiJodHRwOi8vZG9ja2VyOjEwMDQwL2F1dGgvcmVhbG1zLzFzcGlubWlsbGlvbmFpcmUiLCJhdWQiOiJwb3N0bWFuIiwic3ViIjoiMjFlMjc5MmEtNGQ1NS00YTVjLTlmNDctNDcxMDA5ZTEzNmFiIiwidHlwIjoiUmVmcmVzaCIsImF6cCI6InBvc3RtYW4iLCJhdXRoX3RpbWUiOjAsInNlc3Npb25fc3RhdGUiOiJlNDI2OGI0Ny1kM2Y3LTQ0MTEtYmJmNy1jODMxOTk1MGVhNjkiLCJjbGllbnRfc2Vzc2lvbiI6IjFmMzhkYmE5LWRhYWMtNGUyOC1hODdjLTI4MDcyN2YzYzhjNSIsInJlYWxtX2FjY2VzcyI6eyJyb2xlcyI6WyJyb2xlX2FkbWluIiwicm9sZV92aWV3X3VzZXJzIiwicm9sZV9wYXJ0bmVyIiwidW1hX2F1dGhvcml6YXRpb24iLCJyb2xlX3BhcnRuZXJfYWRtaW5pc3RyYXRvciJdfSwicmVzb3VyY2VfYWNjZXNzIjp7InJlYWxtLW1hbmFnZW1lbnQiOnsicm9sZXMiOlsidmlldy11c2VycyJdfSwicmVzb3VyY2Utc2VydmVyIjp7InJvbGVzIjpbInJvbGVfYWRtaW4iLCJyb2xlX3BhcnRuZXIiLCJyb2xlX3BhcnRuZXJfYWRtaW5pc3RyYXRvciJdfSwiYWNjb3VudCI6eyJyb2xlcyI6WyJtYW5hZ2UtYWNjb3VudCIsInZpZXctcHJvZmlsZSJdfX19.UTqGzJEnwzjsYnAIGvFafyJCWpmjVMjttvByX7r-KGtgmiqeKvVFSnisAIic8S8n6lHvAtW_K3s35CWovofHJqia9kEk2eyNZIZQGDM8LCum2KgKBOv4Jqg8H3F54gQzr4Pd17SbavpU38--FqDOHMX8a6L6GLs7yUy7PZ86MTm-B4V49ckleCGt0qMtzXMn8GmA1PnjCk5VpB_XR2FSEzuGfFwiXtq3HmWEGL-EybGRj-1GVNi568N2O1tKrHu8SeM-cg8KHEs5oa_C_lpCTii0OqVx7-NInaPpabua1QjrVtPtqS2f1dXuSMmVNwFRPw8ANHxmK4U9zFLgkBloxg",
"token_type": "bearer",
"id_token": "eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICIxWjZ0SXNXa2JLSUNkSG96eWJHT1QybU90S1p1T3RiMU9lNWVRTlZzLW5ZIn0.eyJqdGkiOiIyMGY1OTgzMC05MTFiLTQwNTctYWFiMi05N2NiZGJhNDEwNDMiLCJleHAiOjE1NTI0MDE1NjMsIm5iZiI6MCwiaWF0IjoxNTUyNDAxMjYzLCJpc3MiOiJodHRwOi8vZG9ja2VyOjEwMDQwL2F1dGgvcmVhbG1zLzFzcGlubWlsbGlvbmFpcmUiLCJhdWQiOiJwb3N0bWFuIiwic3ViIjoiMjFlMjc5MmEtNGQ1NS00YTVjLTlmNDctNDcxMDA5ZTEzNmFiIiwidHlwIjoiSUQiLCJhenAiOiJwb3N0bWFuIiwiYXV0aF90aW1lIjowLCJzZXNzaW9uX3N0YXRlIjoiZTQyNjhiNDctZDNmNy00NDExLWJiZjctYzgzMTk5NTBlYTY5IiwiYWNyIjoiMSIsIm5hbWUiOiIiLCJwcmVmZXJyZWRfdXNlcm5hbWUiOiJhZG1pbiJ9.tf1erOZwlXfIklEfx-RtHQvFA4ioMrgZUQYup1sPDQvrZIJJlUf_S6TtJXb226xLWHpyrBKiX6BHJmq6wKCNdOHwP1Rzr7toA7AdfqtRUtTpvW5ZyfzJod4u3wd55u6W5GFCfHPnaOrNEVexKT8HIEty35l110iX2eOAzVB9JBJ5OsJl9PkJzrAct3DhIchaqwWKPrVD2kebyRVNk4RlNJmRzDsH1br4Wv2F9Tjny5ShffzBbCn47LZDQBOO4VbcGgmzyrpYJ70l1DSChdL3chVihwPttA6kiQUYCux1wQd5MSue8Yu7u-YZbXXswOy9ZXU3mfWDdN2I1u4wX3T7UA",
"not-before-policy": 0,
"session_state": "e4268b47-d3f7-4411-bbf7-c8319950ea69"
}
What am I missing? To me they look the same. The main difference is obviously that one is send through postman/client, while the other is send via server-based php script. I don't see there posibility for problem. Am I wrong?
How can I send curl via php to keycloak so that it returns to me access token?
There are two options for you:
Change client setting as public instead of "confidential" in Access Type combobox (in Client setting)
Add the parameter in request like:
&grant_type=password&client_secret=your_secret_client_value
Refer to http://keycloak-user.88327.x6.nabble.com/keycloak-user-Client-secret-not-provided-in-request-td1936.html

403 response when sending POST data via cURL

I'm trying to send some data to a custom built API that was built by a web development agency. The api is pretty straight forward, and all that I require to do is authorise myself with an authorisation basic header and submit a payload which is just JSON data.
The problem is that the API is responding with 403 every time I send a POST request using cURL. Is there any way that my code could be causing this? or is it an error that is caused by the API/API server? Regardless if the JSON payload is correctly formatted or not, it should still return with a 200 response.
The request is pretty straight forward -
<?php
//I've removed the actual username and password
$headers = array(
'Content-Type: application/json',
'Authorization: Basic '.base64_encode('username:password'));
$empty_array = array();
//Create empty json as an example
$json = json_encode($empty_array);
$url = "https://website.com/import";
//start cURL
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_HEADER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_POST, false);
curl_setopt($ch, CURLOPT_POSTFIELDS,
$json);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_RETURNTRANSFER,true);
$output = curl_exec($ch);
$httpcode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
If I take out the POST data, then it will return with a 404 response. This is the correct behaviour if there is no POST data submitted to the url. (I get a 404 if I navigate to the url via a browser). So I have a theory that the server must have some kind of restrictions on accepting POST data.
Does my code seem correct or am I missing something glaringly obvious? I wan't to rule out that it's a problem caused by my end due to not being able to access the code/server for the API as that is beyond my control.

Not getting any error or success message while integrating NAB payment gateway

I have tried so far:
<?php
$url = "https://demo.transact.nab.com.au/xmlapi/payment";
$ch = curl_init();
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_RETURNTRANSFER,1);
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, "XML=".$xml);
$content=curl_exec($ch);
curl_close($ch);
print_r('<pre>');
print_r($content);
print_r('</pre>');
$array_data = json_decode(json_encode(simplexml_load_string($content)), true);
print_r('<pre>');
print_r($array_data);
print_r('</pre>');
?>
I am not getting any success or error message while trying the same code. Not getting any message in JSON or array format.
It's a NAB Transact payment gateway.
I have to write this as an answer, because of the code examples.
Did you look in the NabTransact Integration Guide, or anything that has been sent to you before you've started this issue? Error 515 means there is a "fatal error due to unknown reasons". Once I've had a similar error, my headers were not right.
You could try to use use CURLOPT_HTTPHEADER since it is not defined:
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
'Content-type: application/xml',
'Content-length: ' . strlen($xml)
));
And making sure $xml is all in one-line.
.
What does the Integration Guide say?
The Integration Guide says the following:
Chapter 8. XML Over HTTP
The structure of the HTTP request and response messages will need to conform to the HTTP 1.1 network protocol. (...) Important: The HTTP
communication between the client als NAB Transact Payment Gateway must
be done via SSL socket so that sensitive information included in the
request and response messages are encrypted.
8.1 Request
POST /test/payment HTTP/1.1
host: www.NABTransact.com.au
content-type: text/xml
content-length: 677
<?xml-rubbish here, all in one-line>
.
8.2 Response
The initial HTTP server response (100 continue) is to indicate that the request has been received and should be ignored. The 200 response should follow with the XML response message. If content length is 0 and no XML response is included then the request could not be understood and no response was produced.
Followed by a XML-response with data.
So, make sure you're using the correct headers in your cURL and using SSL. If you cannot use an official SSL certificate because you're working on localhost, there are tricks in cURL where you can use your own certificate or bypassing the SSL-check.

Post JSON data to an API via PHP

I need to integrate JSON into PHP, more specifically I need to post some information from a php page on our site to initiate an API request which will then send me information back. The information I am sending revolves around login information and I am struggling to work out how I can send this information.
This is the information I need to post:
POST /user/?action=login HTTP/1.1
Host: api.interlinkexpress.com
Content-Type: application/json
Accept: application/json
Authorization: Basic RFNNSVRIOk1ZUEFTU1dE
GEOClient: account/123456
Content-Length: 0
Reading around the subject I have seen that php cURL may be useful however the example I have doesn't contain all the information I need to pass over. Also I am unsure on whether I need to pass it via a button as well:
$data = array("username" => "TESTAPI", "password" => "APITEST");
$data_string = json_encode($data);
$ch = curl_init('http://api.interlinkexpress.com');
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");
curl_setopt($ch, CURLOPT_POSTFIELDS, $data_string);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
'Content-Type: application/json',
'Content-Length: ' . strlen($data_string))
);
$result = curl_exec($ch);
Any help on this matter would be appreciated. I am new to JSON having only learnt about it fleetingly.
edit: I suppose the main thing I'm asking is how do I pass this information to the API in PHP?
POST /user/?action=login HTTP/1.1
Host: api.interlinkexpress.com
Content-Type: application/json
Accept: application/json
Authorization: Basic RFNNSVRIOk1ZUEFTU1dE (this is the login credentials)
GEOClient: account/123456
Content-Length: 0
If you want something more powerful you can use Guzzle that integrates cURL in a really better way.
I don't get exactly what do you mean with passing it via a button. Are you talking just about PHP or also HTML/Javasript?
If you want a button you could proceed with a button that performs a XMLHttpRequest through Javascript, calling the API (that should return an application/json Content-Type), and then process this result via Javascript.
Or you can use cURL to call the API, get the result, json_decode it and do what you want with that.
You should explain better what you want to accomplish.
[EDIT]
Ok, after the clarifications I can tell you that you have to divide the parameters for the API from the settings for the HTTP call to the API (as you already did ^^ ).
So the parameters that will make the API to perform something are
action = login
while all the others are all setting for the HTTP client (cURL or Guzzle) that will perform the calling to the API's url
method = POST
Host = api.interlinkexpress.com
path = /user/
Accept = application/json
Content-Type = application/json
Authorization = Basic
GEOClient = account/123456 (is this a specific header needed from you API?)
Content-Length = 0
So, this is not complete nor tested but should give you a path to follow for adding
$data = array("action" => "login");
$data_string = json_encode($data);
$ch = curl_init(sprintf('%s/%s', 'http://api.interlinkexpress.com', 'user/');
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");
curl_setopt($ch, CURLOPT_POSTFIELDS, $data_string);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
'Content-Type: application/json',
'Content-Length: ' . strlen($data_string)),
'GEOClient: account/123456',
);
// I would suggest you to add the timeout
curl_setopt($ch, CURLOPT_TIMEOUT, 30);
curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_ANY); // or set it to CURLAUTH_BASIC
curl_setopt($ch, CURLOPT_USERPWD, sprintf('%s:%s', $data['username'],$data['password']));
$status_code = curl_getinfo($ch, CURLINFO_HTTP_CODE); //get status code
$result = curl_exec($ch);
I honestly don't get/know where you should send JSON encoded data.
This way you are sending the 'action' as JSON data, but I guess that this is wrong.
Maybe you want to pass the $data_string as the value of a specific field? (like in the example stated from PHP Develoer?)
Work on that, and understand exactly what data you have to pass as JSON and what NOT instead.
I hope to have helped you and gave good suggestions.
Your $data_string is not in format like (field=value).
Nothing to do just pass array into POST.
curl_setopt($ch, CURLOPT_POSTFIELDS, array('Data'=>$data_string));

cURL with PUT method

Is it possible to do a cURL request with the PUT method using only a URL? Here is the URL i would like to be able to call using cURL with the PUT method:
$url = https://url.net/card/activate.xml?card_id=1234567890&application_key=123123&accesskey=abcdef
I was able to make it work using the REST Console(Chrome Extension) but not using cURL. I tried using curl_setopt with CURLOPT_PUT, CURLOPT_INFILE and CURLOPT_INFILESIZE but I was receiving an empty page, no response at all.
This is the headers and curl options I currently have:
$header[] = 'Authorization: Basic abc123';
$header[] = 'Accept: text/xml';
curl_setopt($curl, CURLOPT_CUSTOMREQUEST, 'PUT');
curl_setopt($curl, CURLOPT_URL, $url);
curl_setopt($curl, CURLOPT_HTTPHEADER, $header);
curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false);
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
$output = curl_exec($soap_do);
Currently, with those settings, I'm getting the 411 Length Required error. Would it be possible to make it work like that or am I trying to configure something that will never work?
The HTTP 411 Error
The Web server (running the Web site) thinks that the HTTP data stream sent by the client (e.g. your Web browser or our CheckUpDown robot) should include a 'Content-Length' specification. This is typically used only for HTTP methods that result in the placement of data on the Web server, not the retrieval of data from it.
You need to set the Content Length of your Data
$header[] = 'Content-length: '.strlen($put_data);
OR If you don't have any data, just put 0 there.

Categories