简体   繁体   English

Shopware REST Api - 无效或缺少身份验证

[英]Shopware REST Api - Invalid or missing auth

I'm trying to access the REST api of Shopware. 我正在尝试访问Shopware的REST API。 I'm using version 5.1.3 of Shopware. 我正在使用Shopware的5.1.3版本。 I'm using the code of the documentation . 我正在使用文档的代码。

I always get a http code 400 (Invalid or missing auth) back. 我总是得到一个http代码400(无效或缺少身份验证)。

When I try to access the API via Google Chrome it works after login with http authentication, so the credentials should be OK. 当我尝试通过谷歌浏览器访问API时,它在使用http身份验证登录后工作,因此凭据应该没问题。

I guess the Authentication header Chrome sends differs from the one I send with PHP curl. 我想Chrome发送的身份验证标头与我使用PHP curl发送的标头不同。

With Chrome: 使用Chrome:

Accept:text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Accept-Encoding:gzip, deflate, sdch
Accept-Language:nl-NL,nl;q=0.8,en-US;q=0.6,en;q=0.4
Authorization:Digest username="demo", realm="Shopware REST-API", nonce="7aa6aa7e8089c60e5930cb45ead39197", uri="/api/articles", algorithm=MD5, response="cee77e425508605dfbcf2deda8f83938", opaque="d75db7b160fe72d1346d2bd1f67bfd10", qop=auth, nc=0000001e, cnonce="8b5121e862c4fce1"
Cache-Control:max-age=0
Connection:keep-alive
Cookie:session-1=2d0cb2941684d2767e76ffeb48c7337706cba39c
Host:shopware.example.com
Upgrade-Insecure-Requests:1
User-Agent:Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/48.0.2564.116 Safari/537.36

With PHP Curl 使用PHP Curl

GET /api/articles? HTTP/1.1\r\n
Host: shopware.example.com\r\n
Authorization: Digest username="demo",realm="",nonce="806c9770a53bf2f82b87734a9d8eb98c",uri="/api/articles?",cnonce="60e6c8db046db8f4e63fece37e38f92e",nc=00000001,algorithm=MD5,response="299069d4659af386a4ec7058796267c2",qop="auth",opaque="d75db7b160fe72d1346d2bd1f67bfd10"\r\n
User-Agent: Shopware shopwareApiClient\r\n
Accept: */*\r\n
Content-Type: application/json; charset=utf-8\r\n
Content-Length: 2\r\n

Extra PHP curl directives to get header information: 额外的PHP curl指令来获取头信息:

curl_setopt($this->cURL, CURLINFO_HEADER_OUT, true);
print_r(curl_getinfo($this->cURL, CURLINFO_HEADER_OUT ));

The code I use: 我使用的代码:

<?php

namespace App;

class shopwareApiClient
{

    const METHOD_GET = 'GET';
    const METHOD_PUT = 'PUT';
    const METHOD_POST = 'POST';
    const METHOD_DELETE = 'DELETE';

    protected $validMethods = array(
        self::METHOD_GET,
        self::METHOD_PUT,
        self::METHOD_POST,
        self::METHOD_DELETE
    );
    protected $apiUrl;
    protected $cURL;

    public function __construct($apiUrl, $username, $apiKey)
    {
        $this->apiUrl = rtrim($apiUrl, '/') . '/';
        //Initializes the cURL instance
        $this->cURL = curl_init();
        curl_setopt($this->cURL, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($this->cURL, CURLOPT_FOLLOWLOCATION, false);
        curl_setopt($this->cURL, CURLOPT_USERAGENT, 'Shopware shopwareApiClient');
        curl_setopt($this->cURL, CURLOPT_HTTPAUTH, CURLAUTH_DIGEST);
        curl_setopt($this->cURL, CURLOPT_USERPWD, $username . ':' . $apiKey);
        curl_setopt($this->cURL, CURLOPT_HTTPHEADER, array(
            'Content-Type: application/json; charset=utf-8',
        ));
        curl_setopt($this->cURL, CURLINFO_HEADER_OUT, true);
    }

    public function call($url, $method = self::METHOD_GET, $data = array(), $params = array())
    {
        if (!in_array($method, $this->validMethods))
        {
            throw new Exception('Invalid HTTP-Methode: ' . $method);
        }
        $queryString = '';
        if (!empty($params))
        {
            $queryString = http_build_query($params);
        }
        $url = rtrim($url, '?') . '?';
        $url = $this->apiUrl . $url . $queryString;
        $dataString = json_encode($data);
        curl_setopt($this->cURL, CURLOPT_URL, $url);
        curl_setopt($this->cURL, CURLOPT_CUSTOMREQUEST, $method);
        curl_setopt($this->cURL, CURLOPT_POSTFIELDS, $dataString);
        $result = curl_exec($this->cURL);
        dd(curl_getinfo($this->cURL, CURLINFO_HEADER_OUT ));
        $httpCode = curl_getinfo($this->cURL, CURLINFO_HTTP_CODE);
        return $this->prepareResponse($result, $httpCode);
    }

    public function get($url, $params = array())
    {
        return $this->call($url, self::METHOD_GET, array(), $params);
    }

    public function post($url, $data = array(), $params = array())
    {
        return $this->call($url, self::METHOD_POST, $data, $params);
    }

    public function put($url, $data = array(), $params = array())
    {
        return $this->call($url, self::METHOD_PUT, $data, $params);
    }

    public function delete($url, $params = array())
    {
        return $this->call($url, self::METHOD_DELETE, array(), $params);
    }

    protected function prepareResponse($result, $httpCode)
    {
        echo "<h2>HTTP: $httpCode</h2>";
        if (null === $decodedResult = json_decode($result, true))
        {
            $jsonErrors = array(
                JSON_ERROR_NONE => 'No error occurred',
                JSON_ERROR_DEPTH => 'The maximum stack depth has been reached',
                JSON_ERROR_CTRL_CHAR => 'Control character issue, maybe wrong encoded',
                JSON_ERROR_SYNTAX => 'Syntaxerror',
            );
            echo "<h2>Could not decode json</h2>";
            echo "json_last_error: " . $jsonErrors[json_last_error()];
            echo "<br>Raw:<br>";
            echo "<pre>" . print_r($result, true) . "</pre>";
            return;
        }
        if (!isset($decodedResult['success']))
        {
            echo "Invalid Response";
            return;
        }
        if (!$decodedResult['success'])
        {
            echo "<h2>No Success</h2>";
            echo "<p>" . $decodedResult['message'] . "</p>";
            return;
        }
        echo "<h2>Success</h2>";
        if (isset($decodedResult['data']))
        {
            echo "<pre>" . print_r($decodedResult['data'], true) . "</pre>";
        }
        return $decodedResult;
    }
}

Edit: Found a php bug report which states there is a bug in PHP with Windows on version 5.6 and above. 编辑:发现一个php错误报告 ,其中指出PHP版本5.6及更高版本的PHP存在错误。 I'm using XAMP on Windows. 我在Windows上使用XAMP。 I'm going to try it on linux to see if it does work. 我将在linux上尝试它,看看它是否有用。

The bug report was correct. 错误报告是正确的。 I was using XAMP with PHP 5.6 on Windows. 我在Windows上使用XAMP和PHP 5.6。

After putting my PHP code on a linux machine, the code works. 将我的PHP代码放在linux机器上后,代码就可以了。

Quote bug report: 引用错误报告:

[2015-07-19 09:51 UTC] roeycohen at gmail dot com [2015-07-19 09:51 UTC] romailcohen在gmail dot com

Description: 描述:

trying to use curl_exec with digest authentication does not work properly. 尝试将curl_exec与摘要式身份验证一起使用无法正常工作。 running the test script always fails to pass the security challenge. 运行测试脚本始终无法通过安全挑战。 using the browser or wget directly works perfectly. 使用浏览器或wget直接工作完美。

also, trying to run the same test on another server of mine, works from an amazon linux with php 5.5.21 but does not work from my windows 7 x64 machine with php 5.6.11. 另外,尝试在我的另一台服务器上运行相同的测试,使用php 5.5.21的amazon linux工作,但不能使用我的Windows 7 x64机器与php 5.6.11。

trying to run the test with php 5.5 or 5.4 using CLI on several windows machines caused a complete crush of the php executable. 尝试在几台Windows机器上使用CLI使用php 5.5或5.4运行测试导致了php可执行文件的完全粉碎。

it seems like bug #69088 is related, but this bug also happens on linux (5.5). 似乎bug#69088是相关的,但这个bug也发生在linux(5.5)上。

Test script: 测试脚本:

<?
$curl = curl_init();

$curl_options = [
    CURLOPT_HTTPAUTH => CURLAUTH_ANY,

    CURLOPT_USERPWD => 'test_user:password',
    CURLOPT_URL => 'http://test_user:password@httpbin.org/digest-auth/auth/user/password',
    CURLOPT_HEADER => true,
];
curl_setopt_array($curl, $curl_options);

curl_exec($curl);
curl_close($curl);

Expected result: 预期结果:

 { "authenticated": true, "user": "user" } 

Actual result: 实际结果:

 "Authentication failed" (with header 401) 

[2015-12-28 16:33 UTC] gohel at basicguru dot de [2015-12-28 16:33 UTC] gohel at basicguru dot de

I have the same problem with PHP-clients/scripts and the CalDAV/SabreDAV-framework (also included in Owncloud, Baikal, etc.) on my Apache 2.4.17 (Win32/VC11 from Apachelounge on Win7/64). 我的Apache 2.4.17(Win7 / 64上来自Apachelounge的Win32 / VC11)的PHP客户端/脚本和CalDAV / SabreDAV框架(也包括在Owncloud,Baikal等中)也有同样的问题。

I've played a little bit with different versions of the PHP 5.6.x releases and found the following: 我已经使用不同版本的PHP 5.6.x版本进行了一些操作,并发现了以下内容:

  • php_curl.dll <= v5.6.4 - no problems php_curl.dll <= v5.6.4 - 没问题
  • php_curl.dll v5.6.5/v5.6.6 - crash with Auth_Digest php_curl.dll v5.6.5 / v5.6.6 - 与Auth_Digest崩溃
  • php_curl.dll => v5.6.7 - Auth_Digest failed php_curl.dll => v5.6.7 - Auth_Digest失败

The bug is also in the PHP 5.5 release and PHP 5.4 (last stable PHP_CURL.DLL I've found in v5.4.36) 该错误也出现在PHP 5.5版本和PHP 5.4中(我在v5.4.36中找到的最后一个稳定的PHP_CURL.DLL)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM