我正在python中编写一个使用OAuth / REST等访问Magento服务器的应用程序。
OAuth身份验证已经完成,我有两个消费者令牌& 2访问令牌。在Magento本身,我遵循了众多博客中概述的配置步骤 - 设置REST角色,属性和安全性。消费者和用户权限&角色。我已经过了500次(感觉就是这样!)并且看不到任何错误,用户使用已经授权令牌的REST消费者,用户的角色是管理员,等等&等等。
我注意到在完成OAuth流程后,我尝试将产品发布到Magento(其数据库为空)并收到403拒绝访问时出现问题。获取尝试获得相同的尝试。我为Guest启用了REST API访问,现在Get收到一个空的json数组,当然Post仍然有403 - 这告诉我Magento没有查看OAuth令牌并登录我。
似乎Magento拒绝接受在OAuth身份验证过程中生成的消费者/访问令牌。
是否有我错过的配置步骤,或任何提供超越此障碍的信息?
编辑:下面添加的代码段显示了我用来查询Magento的方法: -
from rauth.session import OAuth1Session
session = OAuth1Session(consumer_key, consumer_secret, access_key, access_secret)
headers = {'Content-Type': 'application/json', 'Accept': 'application/json'}
r = session.get('http://mysite.com/api/rest/products', headers=headers)
print r.json()
输出:{u'messages':{u'error':[{u'message':u'Access denied',u'code':403}]}}
答案 0 :(得分:4)
我无法找到使用rauth库的解决方案,如上例所示,但是能够使用oauthlib / requests_oauthlib使其工作如下: -
from requests_oauthlib import OAuth1 as OAuth
import requests
oauth = OAuth(client_key=consumer_key, client_secret=consumer_secret, resource_owner_key=access_key, resource_owner_secret=access_secret)
h = {'Content-Type': 'application/json', 'Accept': 'application/json'}
r = requests.get(url='http://mysite.com/api/rest/products', headers=h, auth=oauth)
print r
print r.content
print r生成“< Response [200]>”,r.content包含json格式的产品列表。
我猜测rauth错误地计算了nonce值或者编码是关闭的 - 它产生的请求中的某些东西令Magento感到不安,因此拒绝授予访问权限。
答案 1 :(得分:4)
经过数小时思考这个问题,我终于意识到为什么我们中的一些人会收到以下错误:
Invalid auth/bad request (got a 403, expected HTTP/1.1 20X or a redirect)
{"messages":{"error":[{"code":403,"message":"Access denied"}]}}
即使成功授权管理员/客户。
遗憾的是,问题不在于Magento,但很可能是您的服务器配置。
我开始研究Magento Api2代码并意识到他们正在使用Zend_Controller_Request_Http方法“getHeader”来检查oAuth授权。
以下是“getHeader()”
的代码public function getHeader($header)
{
if (empty($header)) {
#require_once 'Zend/Controller/Request/Exception.php';
throw new Zend_Controller_Request_Exception('An HTTP header name is required');
}
// Try to get it from the $_SERVER array first
$temp = 'HTTP_' . strtoupper(str_replace('-', '_', $header));
if (isset($_SERVER[$temp])) {
return $_SERVER[$temp];
}
// This seems to be the only way to get the Authorization header on
// Apache
if (function_exists('apache_request_headers')) {
$headers = apache_request_headers();
if (isset($headers[$header])) {
return $headers[$header];
}
$header = strtolower($header);
foreach ($headers as $key => $value) {
if (strtolower($key) == $header) {
return $value;
}
}
}
return false;
}
Magento类传递给这个函数“Mage_Api2_Model_Auth_Adapter_Oauth”是:
public function isApplicableToRequest(Mage_Api2_Model_Request $request)
{
$headerValue = $request->getHeader('Authorization');
return $headerValue && 'oauth' === strtolower(substr($headerValue, 0, 5));
}
由于正在调用“$ request-> getHeader('Authorization'),这意味着getHeader函数中的$ header var为”Authorization“
// Try to get it from the $_SERVER array first
$temp = 'HTTP_' . strtoupper(str_replace('-', '_', $header));
if (isset($_SERVER[$temp])) {
return $_SERVER[$temp];
}
Zend类然后将“Authorization”转换为“HTTP_AUTHORIZATION”并在$ _SERVER数组中查找它,这就是问题所在,因为在该数组中,Authorization值位于“$ _SERVER ['Authorization']”不是“$ _SERVER ['HTTP_AUTHORIZATION”]“,他们这样做是因为其他变量如CONTENT_TYPE存储为HTTP_CONTENT_TYPE,但授权除外。
然而,似乎Zend意识到了这一点,因此他们编写了以下代码:
// This seems to be the only way to get the Authorization header on
// Apache
if (function_exists('apache_request_headers')) {
$headers = apache_request_headers();
if (isset($headers[$header])) {
return $headers[$header];
}
$header = strtolower($header);
foreach ($headers as $key => $value) {
if (strtolower($key) == $header) {
return $value;
}
}
}
这里的问题是许多服务器都没有启用“apache_request_headers”,如果您遇到此问题,您的托管公司很可能已禁用“apache_request_headers”。
这里有两个解决方案:
替换:
$temp = 'HTTP_' . strtoupper(str_replace('-', '_', $header));
使用:
$temp = ($header == 'Authorization') ? $header : 'HTTP_' . strtoupper(str_replace('-', '_', $header));