Shopware REST Api - 身份验证无效或缺失
Posted
技术标签:
【中文标题】Shopware REST Api - 身份验证无效或缺失【英文标题】:Shopware REST Api - Invalid or missing auth 【发布时间】:2016-06-12 13:56:59 【问题描述】:我正在尝试访问 Shopware 的 REST api。我使用的是 Shopware 5.1.3 版。我正在使用documentation 的代码。
我总是得到一个 http 代码 400(无效或缺少身份验证)。
当我尝试通过 Google Chrome 访问 API 时,它会在使用 http 身份验证登录后工作,因此凭据应该没问题。
我猜 Chrome 发送的身份验证标头与我使用 php curl 发送的不同。
使用 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
使用 PHP 卷曲
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
额外的 PHP curl 指令来获取头信息:
curl_setopt($this->cURL, CURLINFO_HEADER_OUT, true);
print_r(curl_getinfo($this->cURL, CURLINFO_HEADER_OUT ));
我使用的代码:
<?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;
编辑:找到了php bug report,它指出 PHP 与 Windows 5.6 及更高版本存在错误。我在 Windows 上使用 XAMP。我打算在 linux 上试一下,看看能不能用。
【问题讨论】:
【参考方案1】:bug report 是正确的。我在 Windows 上使用 XAMP 和 PHP 5.6。
将我的 PHP 代码放在 linux 机器上后,代码就可以工作了。
引用错误报告:
[2015-07-19 09:51 UTC] roeycohen 在 gmail dot com
说明:
尝试将 curl_exec 与摘要身份验证一起使用无法正常工作。 运行测试脚本总是无法通过安全挑战。 直接使用浏览器或 wget 即可。
另外,尝试在我的另一台服务器上运行相同的测试,可以在 amazon linux 上使用 php 5.5.21,但不能在我的 windows 7 x64 机器上使用 php 5.6.11。
尝试在多台 Windows 机器上使用 CLI 使用 php 5.5 或 5.4 运行测试会导致 php 可执行文件完全崩溃。
似乎错误 #69088 是相关的,但这个错误也发生在 linux (5.5) 上。
测试脚本:
<?
$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);
预期结果:
"authenticated": true, "user": "user"
实际结果:
"Authentication failed" (with header 401)
[2015-12-28 16:33 UTC] gohel at basicguru dot de
我的 Apache 2.4.17(Win32/VC11 来自 Apachelounge on Win7/64)上的 PHP 客户端/脚本和 CalDAV/SabreDAV 框架(也包括在 Owncloud、Baikal 等中)有同样的问题。
我尝试了不同版本的 PHP 5.6.x 版本,发现如下:
php_curl.dll php_curl.dll v5.6.5/v5.6.6 - 使用 Auth_Digest 崩溃 php_curl.dll => v5.6.7 - Auth_Digest 失败该错误也在 PHP 5.5 版本和 PHP 5.4 中(我在 v5.4.36 中找到的最后一个稳定的 PHP_CURL.DLL)
【讨论】:
以上是关于Shopware REST Api - 身份验证无效或缺失的主要内容,如果未能解决你的问题,请参考以下文章