Magento REST API,用户授予管理员角色但仅授予访客访问权限

And*_*ner 7 rest privileges oauth magento python-2.7

我在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()
Run Code Online (Sandbox Code Playgroud)

输出:{u'messages':{u'error':[{u'message':u'Access denied',u'code':403}]}}

小智 5

经过几个小时的思考这个问题,我终于意识到为什么我们中的一些人会收到以下错误:

Invalid auth/bad request (got a 403, expected HTTP/1.1 20X or a redirect) 
{"messages":{"error":[{"code":403,"message":"Access denied"}]}}
Run Code Online (Sandbox Code Playgroud)

即使在成功授权管理员/客户之后。

不幸的是,问题不在于 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;
}
Run Code Online (Sandbox Code Playgroud)

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));
}
Run Code Online (Sandbox Code Playgroud)

由于"$request->getHeader('Authorization') 被调用,这意味着getHeader 函数中的$header 变量是"Authorization"

// Try to get it from the $_SERVER array first
$temp = 'HTTP_' . strtoupper(str_replace('-', '_', $header));
if (isset($_SERVER[$temp])) {
    return $_SERVER[$temp];
}
Run Code Online (Sandbox Code Playgroud)

Zend 类然后将“授权”转换为“HTTP_AUTHORIZATION”并在 $_SERVER 数组中查找它,这就是问题所在,因为在该数组中授权值位于“$_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;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

这里的问题是许多服务器没有启用“apache_request_headers”,如果您遇到这个问题,很可能是您的托管公司禁用了“apache_request_headers”。

这里有2个解决方案:

  1. 联系您的主机并要求他们启用“apache_request_headers”。
  2. 修改 Zend_Controller_Request_Http 类中的 getHeader($header) 函数

代替:

$temp = 'HTTP_' . strtoupper(str_replace('-', '_', $header));
Run Code Online (Sandbox Code Playgroud)

和:

$temp = ($header == 'Authorization') ? $header : 'HTTP_' . strtoupper(str_replace('-', '_', $header));
Run Code Online (Sandbox Code Playgroud)


And*_*ner 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
Run Code Online (Sandbox Code Playgroud)

print r 生成“< Response [200] >”,r.content 包含 json 格式的产品列表。

我猜测 rauth 错误地计算了随机数值,或者编码可能已关闭 - 它生成的请求中的某些内容使 Magento 感到不安,因此拒绝授予访问权限。