如何使用 PHP 签署 AWS API 请求?

2023-12-25

我正在尝试签署 AWS API 请求,然后使用 cURL。

目的是将跟踪号码提交给服务提供商的 API,并使用响应。

我对 AWS API 完全是个菜鸟,经过多次测试后找不到我的错误。

我尝试了很多方法,但都导致{"message":"Forbidden"}.

这是我当前的脚本:

<?php

    $accessKeyId = "AKIA55D**********";   
    $secretAccessKey = "NQ0xcl**********";  
    $method ='GET';
    $uri = '/tracking/shipments';
    $secretKey = $secretAccessKey;
    $access_key = $accessKeyId;
    $region = 'af-south-1';
    $service = 'execute-api';
    $host = "https://api.shiplogic.com";
    $alg = 'sha256';
    $date = new DateTime('Africa/Johannesburg');
    $dd = $date->format( 'Ymd\THis\Z' );
    $amzdate2 = new DateTime( 'Africa/Johannesburg' );
    $amzdate2 = $amzdate2->format( 'Ymd' );
    $amzdate = $dd;
    $algorithm = 'AWS4-HMAC-SHA256';
    $canonical_uri = $uri;
    $canonical_querystring = '';
    $canonical_headers = "host:".$host."\n"."x-amz-date:".$amzdate."\n";
    $signed_headers = 'host;x-amz-date';
    $canonical_request = "".$method."\n".$canonical_uri."\n".$canonical_querystring."\n".$canonical_headers."\n".$signed_headers;
    $credential_scope = $amzdate2 . '/' . $region . '/' . $service . '/' . 'aws4_request';
    $string_to_sign  = "".$algorithm."\n".$amzdate ."\n".$credential_scope."\n".hash('sha256', $canonical_request)."";
   //string_to_sign is the answer..hash('sha256', $canonical_request)//

    $kSecret = 'AWS4' . $secretKey;
    $kDate = hash_hmac( $alg, $amzdate2, $kSecret, true );
    $kRegion = hash_hmac( $alg, $region, $kDate, true );
    $kService = hash_hmac( $alg, $service, $kRegion, true );
    $kSigning = hash_hmac( $alg, 'aws4_request', $kService, true );     
    $signature = hash_hmac( $alg, $string_to_sign, $kSigning ); 
    $authorization_header = $algorithm . ' ' . 'Credential=' . $access_key . '/' . $credential_scope . ', ' .  'SignedHeaders=' . $signed_headers . ', ' . 'Signature=' . $signature;

    $headers = [
                'content-type'=>'application/json', 
                'x-amz-date'=>$amzdate, 
                'Authorization'=>$authorization_header];
 
$curl = curl_init();

curl_setopt_array($curl, array(
CURLOPT_URL => 'https://api.shiplogic.com/tracking/shipments?tracking_reference=M3RPH',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => '',
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 0,
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => 'GET',
CURLOPT_HTTPHEADER => array(
'X-Amz-Date: '.$amzdate.'',
'Authorization: ' . $authorization_header . ''
 ),
));

$response = curl_exec($curl);

curl_close($curl);
echo $response;

我收到的回复是{"message":"Forbidden"}

我究竟做错了什么?


Install 亚马逊的 PHP SDK https://github.com/aws/aws-sdk-php正如评论中已经指出的。

composer require aws/aws-sdk-php

您尝试调用的 API 的文档有1 PHP 代码示例及其使用该 SDK https://api-docs.shiplogic.com/。您所需要做的就是插入您的凭据。

use Aws\Credentials\Credentials;
use Aws\Signature\SignatureV4;
use Psr\Http\Message\RequestInterface;

function sign(
    RequestInterface $request,
    string $accessKeyId,
    string $secretAccessKey
): RequestInterface {
    $signature = new SignatureV4('execute-api', 'af-south-1');
    $credentials = new Credentials($accessKeyId, $secretAccessKey);

    return $signature->signRequest($request, $credentials);
}

您可以看到两个输入$request和返回值是一样的RequestInterface 类型。因此,它为您提供了一个带有正确签名的修改后的请求对象(如果您的密钥和参数有效)。

如果您正在使用curl,您可能还没有这个请求对象。亚马逊的 API 使用PSR-7标准请求接口 https://www.php-fig.org/psr/psr-7/,大多数框架如果有请求对象就会实现这一点。

如果您手头没有请求对象,您可以使用Guzzle 的实现 https://github.com/guzzle/psr7为了它。所需的软件包已经安装为亚马逊SDK的依赖 https://github.com/aws/aws-sdk-php/blob/8f8742caa42b260950320c98ddc5da4926e2373d/composer.json#L20-L21。您可以从 Github 永久链接安装这两个突出显示的软件包。

 $request = new GuzzleHttp\Psr7\Request(
     'GET',
     'https://api.shiplogic.com/tracking/shipments',
     [
         // Maybe you still need headers.
     ]
 );
 $signed_request = sign($request);

 $client = new \GuzzleHttp\Client();
 $response = $client->send($signed_request);

正如评论中提到的,应尽可能避免创建自己的安全组件实现。重写代码以使用此请求对象要容易得多,尤其是对于将来的维护而言。

另请记住,您的凭据可能只是无效,或者无法访问您所请求的资源。乍一看,您的大部分实施似乎都遵循了预期签署协议 https://docs.aws.amazon.com/AmazonS3/latest/API/sig-v4-header-based-auth.html (虽然你只需要 1 个小错误就行不通),因此,如果您确定检查了所有内容,那么事情可能就这么简单。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何使用 PHP 签署 AWS API 请求? 的相关文章

随机推荐

  • 向 R 绘图添加类似 Excel 功能的方法? [关闭]

    很难说出这里问的是什么 这个问题是含糊的 模糊的 不完整的 过于宽泛的或修辞性的 无法以目前的形式得到合理的回答 如需帮助澄清此问题以便重新打开 访问帮助中心 help reopen questions 我一直在研究 R 图形参数 试图让我
  • 使用Intellij IDEA重新加载远程Spring Boot应用程序时出现异常

    我正在尝试使用 spring 设置远程 spring boot 环境devtools http docs spring io spring boot docs current reference html using boot devtoo
  • 将 SharePoint 列表数据提取到单独的 SQL Server 表的最简单方法?

    Edited What is the easiest way to scrape extract SharePoint list data to a separate SQL Server table One condition you r
  • wkhtmltopdf - 背景颜色未填充第二页

    我正在尝试使用 wkhtmltopdf 将 HTML 转换为 PDF 文档 我正在运行的命令是wkhtmltopdf test html test pdf 软件版本 wkhtmltopdf V wkhtmltopdf 0 12 5 with
  • php exec 命令(或类似命令)不等待结果

    我有一个想要运行的命令 但我不希望 PHP 坐等结果 是否可以让 PHP 不等待结果 即只是启动它并继续执行下一个命令 我找不到任何东西 并且不确定它是否可能 我能找到的最好的办法就是有人在一分钟内开始执行 CRON 工作 来自文档 htt
  • 仅在基于范围的循环中迭代奇数(偶数)元素

    假设我们有一个普通数组 或其他支持基于范围的循环的容器 const int N 8 int arr N 0 1 2 3 4 5 6 7 使用索引或迭代器 我们可以循环奇数元素并将索引增加 2 for int i 0 i lt N i 2 s
  • 在 noUISlider 中格式化工具提示

    我在我的 Rails 项目中使用 noUISlider noUiSlider create slider start 3 connect lower step 1 range min 1 max 9 pips mode steps dens
  • 如何设置 GOPRIVATE 环境变量

    我开始研究一个Go项目 它使用来自 Github 私有存储库的一些私有模块 每当我尝试运行时go run main go它给了我一个下面的410 Gone error 验证 github com repoURL 电子邮件受保护 cdn cg
  • Google 的 XSLT 页面索引

    我的网站是使用 XML 作为数据存储并使用 XSLT 作为模板创建的 看来 Google 不太擅长为基于 XML XSLT 的网站建立索引 是否有任何高效 易于实现的软件组件可以仅为 Google bot 索引器呈现 XSLT 如果他们使用
  • 去掉6位数后的经纬度小数部分

    我以这种格式得到纬度和经度 纬度23 132679999999997 经度72 20081833333333 但我想要这种格式 纬度 23 132680 经度 72 200818 我怎样才能转换 double Latitude 23 132
  • 重试 F# 中的计算表达式或其他构造

    我希望能够在 F 中编写一个计算表达式 以便在抛出异常时能够重试操作 现在我的代码如下所示 let x retry fun gt GetResourceX let y retry fun gt GetResourceY let z retr
  • 如何在拖动光标时绘制没有间隙的细线?

    我有以下类 它刷新第 0 层中的 jpeg 文件 第 1 层用于绘制 绘制 草绘与粉碎事物相关的任何内容 但在我的绘画中 当我想画一条细线时 它就断了 因为鼠标光标移动需要慢一些 如何解决鼠标快速移动时线保持连接状态的问题 注释 java
  • 如何使用 Objective C 通过单击分段按钮在 Tableview 上重新加载字典?

    我需要创建一个tableview有两个按钮UISegment control 我正进入 状态JSON反应两个不同arrays有两个keys 对于这两个键我创建了两个buttons 每当我单击分段按钮一 然后Schools键值应该加载到表视图
  • 来自 Azure Function 的 Ping 服务器

    我有以下 Azure 函数 但失败了访问被拒绝 忽略逻辑很奇怪的事实 我只是在做第一次测试 public static void Run TimerInfo myTimer ILogger log List
  • 性能 - 在 Python 中比较 2 个大型字符串列表的最快方法

    我有 Python 列表 其中一个包含大约 13000 个不允许的短语 另一个包含大约 10000 个句子 phrases phrase1 phrase2 phrase with spaces sentences sentence some
  • 使用 AVX 一次性进行 4 个水平双精度求和

    该问题可以描述如下 Input m256d a b c d Output m256d s a 0 a 1 a 2 a 3 b 0 b 1 b 2 b 3 c 0 c 1 c 2 c 3 d 0 d 1 d 2 d 3 到目前为止我所做的工作
  • 新站点的 MVC 或 Webform 架构

    我正在开发一个网站 求职门户 我有2 3年的ASP NET webform开发经验 我想创建一个专业的工作门户网站 以改进和了解更多信息 但试图决定最佳架构 任何建议或建议都会有所帮助 Thanks 嗯 有很多种方法可以回答这个问题 我相信
  • 如何重用mysql中已删除的主键?

    我在 mysql 表中有一个名为 id 的列 它也是自动递增的主键 当我删除行时 它们的 id 也将被删除 从而在我的 id 序列中创建 漏洞 例如 1 2 3 9 10 30 等 有没有办法重新使用这些已删除的 id s Using AL
  • Visual Studio 2015 中缺少重构菜单

    我在 Visual Studio 2015 中找不到右键单击上下文菜单 我知道我的项目或我正在处理的文件没有任何问题 我可以在 Visual Studio 2013 中找到右键单击上下文重构菜单 但是 在 Visual Studio 201
  • 如何使用 PHP 签署 AWS API 请求?

    我正在尝试签署 AWS API 请求 然后使用 cURL 目的是将跟踪号码提交给服务提供商的 API 并使用响应 我对 AWS API 完全是个菜鸟 经过多次测试后找不到我的错误 我尝试了很多方法 但都导致 message Forbidde