我正在为文件上传建立一个拖放界面,以便直接进入S3。我的工作流程是这样的:
- 在丢弃时,我向服务器发出 AJAX 请求,
- 服务器生成并签署 S3 上传策略,
- 客户端完成上传。
签名是使用密钥完成的,如本文中所述。但是,我面临以下问题:
我显然可以做
Aws::getConfig()
并从那里捞出密钥,但这似乎不是一种非常干净的方法。在 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);