【问题标题】:Printing out to a php page using AWS PHP SDK [S3]使用 AWS PHP SDK [S3] 打印到 php 页面
【发布时间】:2021-07-10 12:47:16
【问题描述】:

我正在学习使用 AWS 的 PHP SDK。

我想要实现的是,当一些用户在我的网站上请求一个 .php 页面时。 example.com/listbuckets.php

该页面应返回与我的 IAM 角色关联的存储桶。

这是我的代码:

$s3Client = new S3Client([
    'profile' => 'default',
    'region' => 'eu-west-1',
    'version' => 'latest'
]);

//Listing all S3 Bucket
$buckets = $s3Client->listBuckets();
foreach ($buckets['Buckets'] as $bucket) {
    echo $bucket['Name'] . "\n";
}

?>


使用该代码,通过 CLI 或终端,我可以成功查看我的 S3 存储桶。但是当我通过浏览器请求页面时,它显示 500 Internal Server Error.

我在这里缺少什么?

提前致谢。

编辑: 我尝试通过以下方式传递我的 AWS Creds(密钥/秘密):

$credentials = new Aws\Credentials\Credentials('key', 'secret');

$s3 = new Aws\S3\S3Client([
    'version'     => 'latest',
    'region'      => 'eu-west-1',
    'credentials' => $credentials
]);

如果通过网络浏览器访问,我仍然无法解析 php 页面,这可能是与权限/所有权相关的问题吗?如果我通过终端执行,即使我可以看到我的存储桶 php listbuckets.php

编辑2: 我在

上传递了一个新参数
$s3Client = new Aws\S3\S3Client([
    'version'     => 'latest',
    'region'      => 'eu-west-1',
    'credentials' => $credentials,
    'debug'       => true
]);

现在页面正在响应这段文本:

-> 进入step init,name 'idempotency_auto_fill' ------------------------- -------------- 命令设置为 array(3) { ["instance"]=> string(32) "044155c203a162626f000d004ff45d46" ["name"]=> string(11) "ListBuckets " ["params"]=> array(2) { ["@http"]=> array(1) { ["debug"]=> resource(4) of type (stream) } ["@context"]= > array(0) { } } } 请求设置为 array(0) { } -> 进入 step init,名称 's3.ssec' -------------------- ------------------ 没有变化 -> 进入步骤初始化,名称 's3.source_file' ------------------ -------------------------- 无变化 -> 进入 step init,名称 's3.save_as' ---------- ------------------------------ 没有变化 -> 进入步骤初始化,名称 's3.location' ------ ----------------------------------- 无变化 -> 进入 step init,名称为 's3.auto_encode' - ------------------------------------------------------- 无变化 -> 进入 step init , 名称 's3.head_object' ------------------------------------------- - 没有变化 -> 进入步骤验证,名称 'v alidation' -------------------------------------------------------- 没有变化 ->进入验证步骤,命名为 'input_validation_middleware' ------------------------------------------ ------------------- 无变化 -> 进入步骤构建,名称为 'builder' -------------------- ------------------- request.instance 设置为 00fq4442000004ffw2c46 request.method 设置为 GET request.headers 设置为 array(2) { ["X-Amz- Security-Token"]=> string(7) "[TOKEN]" ["Host"]=> array(1) { [0]=> string(26) "s3.eu-west-1.amazonaws.com" } } request.scheme 设置为 https request.path 设置为 / -> Entering step build, name 'ApiCallMonitoringMiddleware' ------------------------ ---------------------------------- 没有变化->进入步骤构建,名称'' ----- -------------------------- request.instance 从 e33e626cc 更改为 00dw0sq03c45d46 request.headers.User-Agent 设置为 array(1) { [ 0]=> string(50) "aws-sdk-php/3.178.4 OS/Linux/4.19.0-16-cloud-amd64" } -> 进入步骤构建,名称为 'endpoint_parameter' -- - - - - - - - - - - - - - - - - - - - - - - - - 没有变化 - > 进入步骤构建,命名为 'EndpointDiscoveryMiddleware' ----------------------------------------- ----------------- 没有变化 -> 进入步骤构建,名称 's3.checksum' ----------------- ----------------------- 无变化 -> 进入步骤构建,名称 's3.content_type' ------------- --------------------------------- 没有变化 -> 进入步骤构建,名称 's3.endpoint_middleware' --- --------------------------------------------------没有变化 -> 进入步骤构建,名称 's3.bucket_endpoint_arn' ------------------------------------ ----------------- 没有变化 -> 输入步骤符号,名称为 'StreamRequestPayloadMiddleware' --------------------- --------------------------------------- 无变化 -> 输入步骤符号,名称 'invocation -id' ------------------------------------------- request.instance 已更改从 000003a1626c9002f900025d46 到 0e55j00003a1626cy004ff4r3d46 request.headers.aws-sdk-invocation-id 设置为 array(1) { [0 ]=> string(32) "321593e23171d701cdwae9" } -> 输入步骤符号,名称为 'retry' ----------------------------- ------ request.instance 从 dw000qdqd04ff45d46 更改为 0400411626c4210004445d46 request.headers.aws-sdk-retry 设置为 array(1) { [0]=> string(3) "0/0" } -> 进入步骤sign, name 'signer' ------------------------------------ request.instance 从 02z00004ss2004ff45d46 更改为 01626d000045d46 request.headers.x-amz-content-sha256 设置为 array(1) { [0]=> string(64) "ec44298f9b934ca491b7855" } request.headers.X-Amz-Date 设置为 array(1) { [ 0]=> string(16) "25T142413Z" } request.headers.Authorization 设置为 array(1) { [0]=> string(211) "AWS4-HMAC-SHA256 Credential=[KEY]/20210415/eu- west-1/s3/aws4_request, SignedHeaders=host;x-amz-content-sha256;x-amz-date, Signature=[SIGNATURE] }

我编辑了一些值,但来自亚马逊,这个错误与什么有关? 好像是签名错误

编辑 3: 正如我所说,这似乎是一个签名错误,我已经比较了两块代码,一个来自浏览器,另一个来自终端,浏览器请求就停止了。 Entering step sign, name 'signer'

我如何才能像在 ec2 实例中使用终端时那样进行签名(通过浏览器)?

编辑 4: 我进行了很多管理和搜索,发现我应该使用预签名 URL。 使用以下代码,我可以授予用户 20 分钟的生命周期链接,该链接将重定向他并向他显示所有可用的存储桶。

$s3Client = new Aws\S3\S3Client([
    'credentials' => $credentials,
    'region' => 'eu-west-1',
    'version' => '2006-03-01',
]);

$cmd = $s3Client->getCommand('ListBuckets', [
    'Bucket' => '*'
    
]);

$request = $s3Client->createPresignedRequest($cmd, '+20 minutes');

// Get the actual presigned-url
$presignedUrl = (string)$request->getUri();
echo($presignedUrl);

编辑 5: 如果有人想打印 AWS PHP SDK 生成的 url 的结果,请使用这个 php 代码

$result = file_get_contents($presignedUrl);
echo($result);

我终于明白了,所以我要发布答案!

【问题讨论】:

  • 500状态是你的服务器还是AWS返回的?如果它是我们的服务器,那么您应该查看错误日志文件以了解详细信息。
  • @Linek 我编辑了来自 AWS 的回复。

标签: php amazon-web-services amazon-s3 request xmlhttprequest


【解决方案1】:

将代码放在 try/catch 块中。在 catch 中打印错误消息。

您是否已经安装了作曲家?

PHP 中所有活动的错误输出?

【讨论】:

  • 我使用以下命令安装了作曲家。作曲家需要 aws/aws-sdk-php
【解决方案2】:

所以整点是有效的,但我执行错了,我向任何正在学习 AWS PHP SDK 的人推荐这个article,以便他/她可以更好地理解从浏览器/客户端制作预签名 URL 的概念。


让我们分解问题, 场景是,当有人请求我的 listbuckets.php 页面时,该页面应该打印出我所有的 S3 存储桶。好的。

需要的东西: 1- AWS 账户 2- EC2 实例 3- S3 存储桶 4- 通过 SSH 访问 EC2 5- EC2 上的作曲家 6- AWS PHP SDK 安装在您的网络项目的根目录上。

当您拥有所有这些东西时,如果您想向任何用户发出对 AWS 资源有效的匿名请求,您应该使用 presigned-urls

转到您的listbuckets.php

代码:


//Key and Secret are variables that you get from your IAM Acces Management
$credentials = new Aws\Credentials\Credentials('KEY','SECRET');

//Create an S3 Client to communicate with AWS.
$s3Client = new Aws\S3\S3Client([
    'credentials' => $credentials,
    'region' => 'eu-west-1',
    'version' => '2006-03-01',
]);

//Here we specify the command that we want to execute on our AWS resource.
//ListBuckets, Put object... 
//We tell with * to List **all** the buckets
$cmd = $s3Client->getCommand('ListBuckets', [
    'Bucket' => '*'
    
]);

//We make the request, including the command we want to execute and the lifespan //of the url. It will be available only 20min, 10min... Whatever you want.
$request = $s3Client->createPresignedRequest($cmd, '+20 minutes');

// Get the actual presigned-url, with this URL can make the request to AWS and it will be valid, we will be requesting AWS to LIST ALL my S3 buckets.
$presignedUrl = (string)$request->getUri();
echo($presignedUrl . "<br>");
echo "<br>";


//What we are going to get, is an XML file, from that file we want (in my case) //the name only so...
$xml = simplexml_load_file($presignedUrl);
//echo $xml->Buckets->Bucket->Name; 
foreach ($xml->Buckets->Bucket as $namee)
{

    echo $namee->Name . "\n";
}


使用此代码,每次有人询问 listbucket.php 时,它都会在后端生成一个有效请求到 aws,并打印出该请求的响应名称。

就是这样:)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-07-08
    • 2021-06-28
    • 2011-09-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多