php - 验证嵌入式应用设置页面访问是否来自 PHP 中的 Shopify
问题描述
当客户安装应用程序时,他们可以选择单击/admin/apps
页面上应用程序列表中的应用程序名称。
当他们单击该页面时,我的应用程序的 PHP 索引文件会收到这些$_GET
变量:
hmac = some_long_alphanumaeric_hmac
locale = en
protocol = https://
shop = example-shop.myshopify.com
timestamp = 1535609063
为了验证 Shopify 的 webhook,我成功地使用了这个:
function verify_webhook($data, $hmac_header, $app_api_secret) {
$calculated_hmac = base64_encode(hash_hmac('sha256', $data, $app_api_secret, true));
return ($hmac_header == $calculated_hmac);
}
// Set vars for Shopify webhook verification
$hmac_header = $_SERVER['HTTP_X_SHOPIFY_HMAC_SHA256'];
$data = file_get_contents('php://input');
$verified = verify_webhook($data, $hmac_header, MY_APP_API_SECRET);
是否可以验证应用管理页面访问来自安装了应用的 Shopify 客户端?
PS:我已经查看了Embedded Apps API(但我不知道这是否是正确的文档,或者我做错了什么),以及提供的GitHub 示例(没有关于如何验证嵌入式应用程序管理页面访问)。
更新:
我尝试了其他各种方法,一路上发现了一些荒谬的问题,但仍然没有运气。
我理解的方法应该用于验证 Shopify HMAC 类似于以下内容:
function verify_hmac($hmac = NULL, $shopify_app_api_secret) { $params_array = array(); $hmac = $hmac ? $hmac : $_GET['hmac']; unset($_GET['hmac']); foreach($_GET as $key => $value){ $key = str_replace("%","%25",$key); $key = str_replace("&","%26",$key); $key = str_replace("=","%3D",$key); $value = str_replace("%","%25",$value); $value = str_replace("&","%26",$value); $params_array[] = $key . "=" . $value; } $params_string = join('&', $params_array); $computed_hmac = hash_hmac('sha256', $params_string, $shopify_app_api_secret); return hash_equals($hmac, $computed_hmac); }
但是该行通过编码为...$params_string = join('&', $params_array);
导致了一个烦人的问题。使用结果同样荒谬。在这里发现其他人有同样的问题。基本上通过编码as来解决,到达.×tamp
xtamp
http_build_query($params_array)
&
&
$params_string = join('&', $params_array);
我的最终版本是这样的,但仍然无法正常工作(所有注释代码都是我尝试过的其他代码无济于事):
function verify_hmac($hmac = NULL, $shopify_app_api_secret) { $params_array = array(); $hmac = $hmac ? $hmac : $_GET['hmac']; unset($_GET['hmac']); // unset($_GET['protocol']); // unset($_GET['locale']); foreach($_GET as $key => $value){ $key = str_replace("%","%25",$key); $key = str_replace("&","%26",$key); $key = str_replace("=","%3D",$key); $value = str_replace("%","%25",$value); $value = str_replace("&","%26",$value); $params_array[] = $key . "=" . $value; // This commented out method below was an attempt to see if // the imporperly encoded query param characters were causing issues /* if (!isset($params_string) || empty($params_string)) { $params_string = $key . "=" . $value; } else { $params_string = $params_string . "&" . $key . "=" . $value; } */ } // $params_string = join('&', $params_array); // echo $params_string; // $computed_hmac = base64_encode(hash_hmac('sha256', $params_string, $shopify_app_api_secret, true)); // $computed_hmac = base64_encode(hash_hmac('sha256', $params_string, $shopify_app_api_secret, false)); // $computed_hmac = hash_hmac('sha256', $params_string, $shopify_app_api_secret, false); // $computed_hmac = hash_hmac('sha256', $params_string, $shopify_app_api_secret, true); $computed_hmac = hash_hmac('sha256', http_build_query($params_array), $shopify_app_api_secret); return hash_equals($hmac, $computed_hmac); }
解决方案
如果您从 Shopify 中获得成功,您要做的第一件事就是检查您的持久层是否已注册商店。如果你这样做了,并且你有某种设置的会话,你可以自由地将你的应用程序呈现给那个商店。如果您没有持久化商店,则通过 oAuth 周期获取要在商店上使用的身份验证令牌,该令牌与商店和新会话一起保留。
对于您商店中接收 webhook 的任何路由或端点,这些请求当然没有会话,因此您使用 HMAC 安全方法来确定要做什么。因此,您的问题显然跨越了两个不同的概念,每个概念的处理方式都不同。该文档非常清楚地说明了这些差异。
推荐阅读
- angular - 离子 5 中的更新值
- javascript - SVG 路径未按预期设置动画的问题
- ruby - <<~ 和 & 的这个红宝石错误是什么?意思是?
- javascript - 如何在三元运算符或布尔运算符中处理布尔值本身?
- angular - 如何使用角度在for循环中使用正确的过滤器
- powershell - 如果 A 列匹配,Powershell CSV 删除行然后从整个文件中删除
- python - 如何在 python 中忽略 .csv 文件中的 Nan?
- packer - Packer 如何按顺序运行两个配置器
- python - 使用 seaborn 在特定 x 轴点标记图
- elasticsearch - ElasticSearch:布尔/术语搜索不区分大小写