php - oAuth 1.0 REST API 与 Magento 1.9,如何像邮递员一样获得 oauth_signature?
问题描述
我正在尝试在 php 中访问 Magento 1.9 REST API,它仅支持 oAuth 1.0 中的身份验证。
现在,我让它在 Postman 中工作,但它正在做某种魔法来执行它没有公开的 oAuth。它甚至有一个用于请求代码的按钮,但是随机数、时间和签名必须随着每个请求而改变。
我正在使用消费者密钥、消费者密码、访问令牌和访问密码向 example.com/api/rest/products(生产站点,为隐私更改 url)发出 GET 请求。它返回所有产品的正确响应。这是它输出的卷曲代码......
<?php
$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_URL => "https://www.example.com/api/rest/products",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => array(
"Authorization: OAuth oauth_consumer_key=\"some_key\",oauth_token=\"some_token\",oauth_signature_method=\"HMAC-SHA1\",oauth_timestamp=\"1529691153\",oauth_nonce=\"0fVylxHPUqv\",oauth_version=\"1.0\",oauth_signature=\"LTJHEp2A5mczD3xrYxbWW2BHlQk%3D\"",
"Cache-Control: no-cache",
"Content-Type: application/json",
"Postman-Token: d684d11c-498e-4760-8709-76777e8ea75d"
),
));
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}
这不起作用,每次都失败,因为已经使用了随机数。如果我更改随机数,它会说签名无效。
这是 Magento 的古老文档推荐的代码,该代码因 403 Not Authorized 而失败。
$baseUrl = 'https://www.example.com';
$callbackUrl = 'http://otherexample.test/test';
$temporaryCredentialsRequestUrl = $baseUrl."/oauth/initiate?oauth_callback=" . urlencode($callbackUrl);
$adminAuthorizationUrl = $baseUrl.'/admin/oauth_authorize';
$accessTokenRequestUrl = $baseUrl.'/oauth/token';
$apiUrl = $baseUrl.'/api/rest';
$consumerKey = 'some_key';
$consumerSecret = 'some_secret';
session_start();
if(! isset($_SESSION['state'])) {
$_SESSION['state'] = null;
}
if (!isset($_GET['oauth_token']) && isset($_SESSION['state']) && $_SESSION['state'] == 1) {
$_SESSION['state'] = 0;
}
try {
$authType = ($_SESSION['state'] == 2) ? OAUTH_AUTH_TYPE_AUTHORIZATION : OAUTH_AUTH_TYPE_URI;
$oauthClient = new \OAuth($consumerKey, $consumerSecret, OAUTH_SIG_METHOD_HMACSHA1, $authType);
$oauthClient->enableDebug();
if (!isset($_GET['oauth_token']) && !$_SESSION['state']) {
$requestToken = $oauthClient->getRequestToken($temporaryCredentialsRequestUrl);
$_SESSION['secret'] = $requestToken['oauth_token_secret'];
$_SESSION['state'] = 1;
header('Location: ' . $adminAuthorizationUrl . '?oauth_token=' . $requestToken['oauth_token']);
exit;
} else if ($_SESSION['state'] == 1) {
$oauthClient->setToken($_GET['oauth_token'], $_SESSION['secret']);
$accessToken = $oauthClient->getAccessToken($accessTokenRequestUrl);
$_SESSION['state'] = 2;
$_SESSION['token'] = $accessToken['oauth_token'];
$_SESSION['secret'] = $accessToken['oauth_token_secret'];
header('Location: ' . $callbackUrl);
exit;
} else {
$oauthClient->setToken($_SESSION['token'], $_SESSION['secret']);
$resourceUrl = $apiUrl . "/products";
$oauthClient->fetch($resourceUrl, array(), 'GET', array('Content-Type' => 'application/json'));
$productsList = json_decode($oauthClient->getLastResponse());
print_r($productsList);
}
} catch (\OAuthException $e) {
print_r($e->getMessage());
echo "<br/>";
print_r($e->lastResponse);
}
基本上,我认为我需要像邮递员一样生成随机数和签名。我给邮递员我的访问令牌和秘密,但这当然不在响应中,因为秘密永远不应该。那么它是如何做到的呢?每次我在邮递员中运行一个请求时,它都会成功,并且代码示例中有不同的数据。每次我在 php 中运行它时,它都会因未授权而失败。
我更喜欢使用像 Guzzle 这样更面向对象的东西而不是 curl,但我会尽我所能让这个外部站点能够使用 Magento 1.x REST API。
解决方案
是的,您必须为每个发送的请求生成一个随机数。
let nonceObj = Math.random()
.toString(36)
.replace(/[^a-z]/, "")
.substr(2);
这就是我在 JS 中所做的。
推荐阅读
- alpine.js - 如何在基于数组的复选框的for-circle中定义x-model?
- c - 在 xcode 中将“终端”设置为默认的“控制台”
- python - 带有 base64 编码图像的 Python Face_Recognition
- game-development - 在 godot 的乒乓球比赛中实例化球时出错
- wordpress - 小部件 wordpress 的缺少样式选项卡
- python - 在并行 NEAT-Python 中保存最佳基因组
- node.js - 如何在打字稿/节点服务器中允许别名?
- php - 根据用户角色和页面显示标题(Wordpress)
- firebase - 我可以限制对 Firebase 项目中特定应用的访问吗?
- time - 为 chrome 扩展提供免费试用期的最佳方式是什么?