使用实例配置文件凭证对 S3 上传策略进行签名


Sign S3 upload policy using Instance Profile credentials

我正在为文件上传建立一个拖放界面,以便直接进入S3。我的工作流程是这样的:

  1. 在丢弃时,我向服务器发出 AJAX 请求,
  2. 服务器生成并签署 S3 上传策略,
  3. 客户端完成上传。
策略

签名是使用密钥完成的,如本文中所述。但是,我面临以下问题:

  1. 我显然可以做Aws::getConfig()并从那里捞出密钥,但这似乎不是一种非常干净的方法。

  2. 在 EC2 上部署时,我根本无法访问私有密钥,因为我使用的是实例角色,因此我不必将凭证存储在服务器本身上。

在这两种情况下,我都可以绕过 SDK 并手动完成,所以真正的问题是:这可以使用 SDK 完成吗,如果是,如何完成?

事实证明,这只需要在 API 中进行一些挖掘。可以从您通过 Aws'Common'Aws::get() 实例化的任何客户端中提取凭据。

// create builder; not passing credentials here
$aws = Aws'Common'Aws::factory(array(
    'region' => 'us-east-1',
));
$s3 = $aws->get('s3');
// get credentials interface
$credentials = $s3->getCredentials();

要对策略字符串进行签名,您需要一个 S3Signature 的实例。根据AbstractClient::getSignature()的文档,您似乎无法从S3Client获得此信息,但从代码的这一部分来看,您似乎可以。

最后一步是调用 ::signString() 方法来生成签名:

$policy = base64_encode(json_encode($policy_data));
$signer = $s3->getSignature();
$signature = $signer->signString($policy, $credentials);

内部调用$credentials->getSecretKey(),必要时从元数据服务加载必要的凭证;否则,它使用传递给Aws::factory()的凭证。

更新

也可以在没有任何客户端的情况下执行此操作:

$credentials = Aws'Common'Credentials'Credentials::factory();
$signer = new S3Signature();
$signature = $signer->signString($policy, $credentials);