0

I am trying to use the Magento 2 Rest API, using token authorization. I can successfully POST user/password to /rest/V1/integration/admin/token/, and I get a token returned. But when I try to GET data back from one of the endpoints using the token in an Authorization Bearer heading, I get an HTTP 401 Basic Authentication error. The problem is that the server requires Basic Authentication, but there is no way I know of to get both Basic and Bearer authentication into one request. If I just specify the Basic header on the GET request then I get a Magento message back to tell me I don't have access to the resource, which is fair enough since I haven't given it a token.

My code is:

<?php

// Get handle for token retrieval
$userData = array("username" => "user", "password" => "password!");
$ch = curl_init("https://my.magento/rest/V1/integration/admin/token/");

// Set options
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($userData));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, array("Content-Type: application/json", "Content-Length: " . strlen(json_encode($userData))));
curl_setopt($ch, CURLOPT_VERBOSE, true);
$verbose = fopen('/tmp/curl.log', 'w+');
curl_setopt($ch, CURLOPT_STDERR, $verbose);

// Get token
$token = curl_exec($ch);
echo "Token returned: " . $token . "<BR><BR>";

// Display log
rewind($verbose);
$verboseLog = stream_get_contents($verbose);
echo "Verbose information 1:\n<pre>", htmlspecialchars($verboseLog), "</pre>\n";

echo "About to get product<BR>";

// Get handle for product types
$ch = curl_init("https://my.magento/rest/V1/products/types/");

// Set options
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "GET");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, array("Content-Type: application/json", "Authorization: Bearer " . json_decode($token)));
curl_setopt($ch, CURLOPT_VERBOSE, true);
$verbose = fopen('/tmp/curl.log', 'w+');
curl_setopt($ch, CURLOPT_STDERR, $verbose);

// Get types
$result = curl_exec($ch);
echo "Result: " . $result . "<BR>"; 

// Display log
rewind($verbose);
$verboseLog = stream_get_contents($verbose);
echo "<BR>Verbose information 2:\n<pre>", htmlspecialchars($verboseLog), "</pre>\n";

?>

And the browser output is:

Tokenreturned: "t8iskt68xlo5frf9hhtc1lk8wmqzbzx8"

Verbose information 1: 
* About to connect() to my.magento port 443 (#2)
*   Trying nn.nn.nn.nn...
* Connected to mymagento (nn.nn.nn.nn) port 443 (#2)
*   CAfile: /etc/pki/tls/certs/ca-bundle.crt
  CApath: none
* SSL connection using TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
* Server certificate:
*     subject: CN=ssl379212.cloudflaressl.com,OU=PositiveSSL Multi-Domain,OU=Domain Control Validated
*     start date: Oct 26 00:00:00 2018 GMT
*     expire date: May 04 23:59:59 2019 GMT
*     common name: ssl379212.cloudflaressl.com
*     issuer: CN=COMODO ECC Domain Validation Secure Server CA 2,O=COMODO CA Limited,L=Salford,ST=Greater Manchester,C=GB
> POST /rest/V1/integration/admin/token/ HTTP/1.1
Host: sand2.firetoys.co.uk
Accept: */*
Content-Type: application/json
Content-Length: 48

* upload completely sent off: 48 out of 48 bytes
< HTTP/1.1 200 OK
< Date: Wed, 31 Oct 2018 12:50:01 GMT
< Content-Type: application/json; charset=utf-8
< Content-Length: 34
< Connection: keep-alive
< Set-Cookie: __cfduid=d69af7d1f0a1205231a8867c1f45875621540990201; expires=Thu, 31-Oct-19 12:50:01 GMT; path=/; domain=.my.magento; HttpOnly
< X-Frame-Options: SAMEORIGIN
< X-UA-Compatible: IE=edge
< Pragma: no-cache
< Expires: -1
< Cache-Control: no-store, no-cache, must-revalidate, max-age=0
< Accept-Ranges: bytes
< Set-Cookie: PHPSESSID=9p378rsfito8gfocnrufucssh6; expires=Wed, 31-Oct-2018 13:50:01 GMT; Max-Age=3600; path=/; domain=sand2.firetoys.co.uk; secure; HttpOnly
< Expect-CT: max-age=604800, report-uri="https://report-uri.cloudflare.com/cdn-cgi/beacon/expect-ct"
< Server: cloudflare
< CF-RAY: 47263eb629ea0ce9-LHR
< 
* Connection #2 to host my.magento left intact
About to get product
Result: 

Verbose information 2: 
* About to connect() to my.magento port 443 (#3)
*   Trying nn.nn.nn.nn...
* Connected to my.magento (nn.nn.nn.nn) port 443 (#3)
*   CAfile: /etc/pki/tls/certs/ca-bundle.crt
  CApath: none
* SSL connection using TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
* Server certificate:
*     subject: CN=ssl379212.cloudflaressl.com,OU=PositiveSSL Multi-Domain,OU=Domain Control Validated
*     start date: Oct 26 00:00:00 2018 GMT
*     expire date: May 04 23:59:59 2019 GMT
*     common name: ssl379212.cloudflaressl.com
*     issuer: CN=COMODO ECC Domain Validation Secure Server CA 2,O=COMODO CA Limited,L=Salford,ST=Greater Manchester,C=GB
> GET /rest/V1/products/types/ HTTP/1.1
Host: sand2.firetoys.co.uk
Accept: */*
Content-Type: application/json
Authorization: Bearer t8iskt68xlo5frf9hhtc1lk8wmqzbzx8

< HTTP/1.1 401 Unauthorized
< Date: Wed, 31 Oct 2018 12:50:01 GMT
< Content-Length: 0
< Connection: keep-alive
< Set-Cookie: __cfduid=d38c9e4bc3019d9ac55c7f68f5c5ca1161540990201; expires=Thu, 31-Oct-19 12:50:01 GMT; path=/; domain=.my.magento; HttpOnly
< X-Varnish: 7995397
< WWW-Authenticate: Basic
< Expect-CT: max-age=604800, report-uri="https://report-uri.cloudflare.com/cdn-cgi/beacon/expect-ct"
< Server: cloudflare
< CF-RAY: 47263eb70f5b3512-LHR
< 
* Connection #3 to host my.magento left intact

Any ideas?

1

Make sure that the admin account you are using has the correct permissions set and is allowed to get data from the endpoint.

  • The user has access to everything. I don't think HTTP is letting me get as far as that - if I put in the basic authentication header in place of the bearer token then I get a Magento message about not having access as I haven't supplied a token. If I use the bearer token authorization then I think HTTP is rejecting me before I get to Magento. – Matthew Nov 1 '18 at 17:33
  • I checked the code on 2 magento 2.2.6 instances and it works as expected, so most probably the problem lies with some settings in magento (check token valid time) or server (nginx/apache) configuration. If you have access to the server check logs in var/log and var/report/ to see if there is something. The complete null of response suggests some exception is raised during script execution. – Zefiryn Nov 1 '18 at 23:06
  • I have some access to the server, but I can't look into most of the files in /var/log (and there doesn't appear to be a /var/report). Which files should I be looking at? But as I say if I run the request with Basic authentication but without the Bearer token I get a Magento response saying I don't have access, as I would expect. I would have thought that if the problem was that the token when I do send it is invalid in some way, then I would get the same Magento error rather than nothing. Anyway, I should know more when I try with basic authentication switched off soon. – Matthew Nov 3 '18 at 8:45
  • I meant var/log and var/report in the magento folder, not system /var folder. If you see error response while not providing the token but nothing when do then I suspect there is an exception and due to production mode being set on the server you have no information about it. – Zefiryn Nov 4 '18 at 8:04
0

OK, I have had a chance to test this with basic authentication switched off, and everything works fine. Basic authentication will be off anyway in the live environment, so in the absence of any method of applying both basic and bearer authentication in one request I will have to live with having to store up my testing for occasional days when basic can be switched off.

Thanks to @Zefiryn for your responses.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.