By peterk900 on
This script was exported from Postman and edited to provide Basic Authentication.
$curl = curl_init();
// Your credentials
$username = "<user>";
$password = "<password>";
// Encode credentials in Base64
$credentials = base64_encode($username . ":" . $password);
curl_setopt_array($curl, array(
CURLOPT_URL => 'https://peter900.example.org/web/node?_format=json',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => '',
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 0,
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_POSTFIELDS =>'{
"type":[
{
"target_id":"article"
}
],
"title":[
{
"value":"Create node99999"
}
],
"body":[
{
"value":"Node Body",
"format":"basic_html"
}
]
}',
CURLOPT_HTTPHEADER => array(
'Content-Type: application/json',
'Authorization: Basic {$credentials}', // Add Basic Auth header
),
));
$response = curl_exec($curl);
curl_close($curl);
echo $response;Running this script gives the following error message..
Symfony\Component\HttpKernel\Exception\UnauthorizedHttpException: No authentication credentials provided. in Drupal\basic_auth\Authentication\Provider\BasicAuth->challengeException() (line 180 of /var/www/vhosts/xxx.org/peter900.xxx.org/web/core/modules/basic_auth/src/Authentication/Provider/BasicAuth.php).
I don't understand while the parameters and authentication included in Postman creates a node but when I run in a browser what I believe is identical code, it fails saying "No authentication credentials provided". Any help much appreciated. Thanks.
Comments
I've corrected the Authorisation key...
I now realise why no authentication credentials were picked up - a php variable was included inside the string!
I've replaced the variable with the base64 encoded value...
But I still have a problem. The error message is now...
Path: /web/node?_format=json. Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException: in Drupal\Core\Routing\AccessAwareRouter->checkAccess() (line 117 of /var/www/vhosts/xxx.org/peter.xxx.org/web/core/lib/Drupal/Core/Routing/AccessAwareRouter.php).
Basic Auth works but getting Access Denied.
Now auth seems correct. The new error looks like a permission issue, not an authentication issue. Please check whether this user has permission to create Article nodes via the JSON/REST endpoint.
Thanks
The credentials used in my first post - administrator - used in the cURL code were the same as I used in Postman. But, based on your suggestion, I created a new role - content editor and tested this in Postman (node created successfully, as before) and then with the same cURL script, updated for the new user and password, bas64_encoded. This failed with the same AccessDeniedHttpException error. Interestingly the Postman run shows the content editor's user name in log messages but the cURL script shows the user as Anonymous (not verified).
I checked that permissions for both administrator and content editor are granted for External Entities REST: Create new external entity and JSONAPI: Create new external entity.
There must be some difference in the way Postman posts the data compared to the browser run cURL script.
If there's any more information you need or tests to carry out, please let me know. Thanks again for your help so far.
cURL request still treated as anonymous
Looks like in cURL the request is still going as anonymous. Maybe the Authorization header isn’t being sent correctly. Try using CURLOPT_USERPWD or check headers once.
Do you mean something like this...?
OR
And does it matter where I put this in the script?
[I forgot to mention that $response displayed when I run the script is...
{"message":""}
... and the script log message is classified as a warning, not an error. ]
Thanks for sticking with this.
Using CURLOPT_HTTPHEADER, I get a new error
I've changed the code as follows...
The error message is now...
Symfony\Component\HttpKernel\Exception\NotAcceptableHttpException: No route found for the specified format. Supported formats: html. in Drupal\Core\Routing\RequestFormatRouteFilter->filter() (line 65 of /var/www/vhosts/moormission.org/peter900.example.org/web/core/lib/Drupal/Core/Routing/RequestFormatRouteFilter.php).
Does supported formats refer to the body format basic_html? I don't see how this can be a problem because there is no error with a Postman post. But interestingly the error type is now "Client Error", not "Access denied". The user remains "Anonymous (not verified)" and $response is {"message":"No route found for the specified format. Supported formats: html."}
The link I quoted in my last post said that some services don't like a space in Authorization:Basic, so I've made that change.
Does this give any further clues?
P.S Removing the JSON which sets a body value gives the same error message, so it's not referring to the node's text format.
Solved...
Here is an extract of the code which creates nodes in D11.3.1 from JSON submitted by an https post. In this code the articles page is created by a module which takes the JSON and creates the article node, rather than the earlier posts which included the JSON in the cURL script. [This new script is one that worked fine in D10.x with un-encoded credentials, something with D11 doesn't allow.]
It uses base64 encoded credentials which are included in an array, $headers, along with Content-Type. This array is then processed with the statemement curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);