1

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: 2018年10月31日 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: 2018年10月31日 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?

Haim
2,14219 silver badges37 bronze badges
asked Nov 1, 2018 at 14:54

3 Answers 3

1

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

answered Nov 1, 2018 at 16:12
4
  • 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. Commented Nov 1, 2018 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. Commented Nov 1, 2018 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. Commented Nov 3, 2018 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. Commented Nov 4, 2018 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.

answered Nov 5, 2018 at 8:39
0

Basic authentication has to be disabled for rest api requests because one can't authorize with both basic auth and bearer token in the same request, to disable basic auth for api-requests in webserver config use something like:

  • nginx:

    map $request_uri $auth_uri {
     ~^/rest/ "off";
     default "Restricted";
    }
    server {
     [..]
     auth_basic $auth_uri;
     [..]
    
  • apache (with mod setenvif enabled):

     <VirtualHost *:443>
     [..]
     SetEnvIf Request_URI ^/rest/ noauth=1
     <Directory /path/to/webroot>
     AuthType Basic
     [..]
     Require valid-user
     Allow from env=noauth
     Satisfy any
     Deny from env!=noauth
    
answered Jan 29 at 14:05

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.