Jos*_*Lam 53 amazon-s3 amazon-web-services aws-php-sdk
我已经在网上搜索了两天以上,可能已经浏览了大多数在线记录的场景和解决方法,但到目前为止我没有任何作用.
我在运行PHP 5.3的AWS SDK for PHP V2.8.7上.我正在尝试使用以下代码连接到我的S3存储桶:
// Create a `Aws` object using a configuration file
$aws = Aws::factory('config.php');
// Get the client from the service locator by namespace
$s3Client = $aws->get('s3');
$bucket = "xxx";
$keyname = "xxx";
try {
$result = $s3Client->putObject(array(
'Bucket' => $bucket,
'Key' => $keyname,
'Body' => 'Hello World!'
));
$file_error = false;
} catch (Exception $e) {
$file_error = true;
echo $e->getMessage();
die();
}
//
Run Code Online (Sandbox Code Playgroud)
我的config.php文件如下:
<?php
return array(
// Bootstrap the configuration file with AWS specific features
'includes' => array('_aws'),
'services' => array(
// All AWS clients extend from 'default_settings'. Here we are
// overriding 'default_settings' with our default credentials and
// providing a default region setting.
'default_settings' => array(
'params' => array(
'credentials' => array(
'key' => 'key',
'secret' => 'secret'
)
)
)
)
);
Run Code Online (Sandbox Code Playgroud)
它产生以下错误:
我们计算的请求签名与您提供的签名不匹配.检查您的密钥和签名方法.
我已经检查了我的访问密钥和秘密至少20次,生成了新的密钥,使用不同的方法传递信息(即配置文件并在代码中包含凭据),但目前没有任何工作.
Jos*_*Lam 49
经过两天的调试,我终于发现了问题......
我分配给对象的键以句点开始,即..\images\ABC.jpg,这导致错误发生.
我希望API提供更有意义和相关的错误信息,唉,我希望这会帮助其他人!
Ros*_*don 29
我刚刚遇到过这种情况,我有点不好意思地说,这是因为我使用的是 HTTP POST 请求而不是 PUT。
尽管我很尴尬,但我还是想分享一下,以防有人因此而苦恼一个小时。
Ale*_*ine 22
我用错误的凭据收到此错误.我认为当我最初粘贴它时会有隐形字符.
Ole*_*leg 16
我在 nodejs 中遇到了同样的错误。但是添加signatureVersions3 构造函数帮助了我:
const s3 = new AWS.S3({
apiVersion: '2006-03-01',
signatureVersion: 'v4',
});
Run Code Online (Sandbox Code Playgroud)
尝试复制具有某些UTF8字符的对象时,我遇到了同样的问题.下面是一个JS示例:
var s3 = new AWS.S3();
s3.copyObject({
Bucket: 'somebucket',
CopySource: 'path/to/Weird_file_name_ðO?pi?u.jpg',
Key: 'destination/key.jpg',
ACL: 'authenticated-read'
}, cb);
Run Code Online (Sandbox Code Playgroud)
通过编码CopySource解决 encodeURIComponent()
另一个可能的问题可能是元值包含非 US-ASCII 字符。对我来说,在将值添加到 putRequest 时,它有助于对值进行 UrlEncode:
request.Metadata.Add(AmzMetaPrefix + "artist", HttpUtility.UrlEncode(song.Artist));
request.Metadata.Add(AmzMetaPrefix + "title", HttpUtility.UrlEncode(song.Title));
Run Code Online (Sandbox Code Playgroud)
实际上在 Java 中我遇到了同样的错误。花了 4 个小时调试它之后,我发现问题出在 S3 对象中的元数据中,因为在 s3 文件中放置缓存控件时有空间。这个空间在 1.6 中是允许的。*版本,但在 1.11.* 中是不允许的,因此会引发签名不匹配错误
如果上述其他解决方案都不适合您,请尝试使用
aws configure
Run Code Online (Sandbox Code Playgroud)
此命令(AWS CLI 入门)将打开一组选项,询问密钥、区域和输出格式。
希望这可以帮助!
我的 AccessKey 有一些特殊字符没有正确转义。
我在复制/粘贴密钥时没有检查特殊字符。绊倒了我几分钟。
一个简单的反斜杠修复了它。示例(显然不是我真正的访问密钥):
secretAccessKey: 'Gk/JCK77STMU6VWGrVYa1rmZiq+Mn98OdpJRNV614tM'
变成
secretAccessKey: 'Gk\/JCK77STMU6VWGrVYa1rmZiq\+Mn98OdpJRNV614tM'
就我而言,我将 S3 url 解析为其组件。
例如:
Url: s3://bucket-name/path/to/file
Run Code Online (Sandbox Code Playgroud)
被解析为:
Bucket: bucket-name
Path: /path/to/file
Run Code Online (Sandbox Code Playgroud)
路径部分包含前导“/”导致请求失败。
对我来说,我使用 axios 并且默认它发送标头
content-type: application/x-www-form-urlencoded
Run Code Online (Sandbox Code Playgroud)
所以我改为发送:
content-type: application/octet-stream
Run Code Online (Sandbox Code Playgroud)
并且还必须将此 Content-Type 添加到 AWS 签名
const params = {
Bucket: bucket,
Key: key,
Expires: expires,
ContentType = 'application/octet-stream'
}
const s3 = new AWS.S3()
s3.getSignedUrl('putObject', params)
Run Code Online (Sandbox Code Playgroud)
小智 5
在 aws-php-sdk 的先前版本中,在弃用该S3Client::factory()方法之前,您可以将文件路径的一部分(或Key在S3Client->putObject()parameters 中调用)放置在bucket 参数上。我在生产中使用了一个文件管理器,使用 v2 SDK。由于工厂方法仍然有效,我没有在更新到~3.70.0. 今天我花了两个小时的大部分时间来调试为什么我开始收到这个错误,它最终是由于我传递的参数(曾经有效):
$s3Client = new S3Client([
'profile' => 'default',
'region' => 'us-east-1',
'version' => '2006-03-01'
]);
$result = $s3Client->putObject([
'Bucket' => 'awesomecatpictures/catsinhats',
'Key' => 'whitecats/white_cat_in_hat1.png',
'SourceFile' => '/tmp/asdf1234'
]);
Run Code Online (Sandbox Code Playgroud)
我必须将catsinhats存储桶/密钥路径的一部分移动到Key参数,如下所示:
$s3Client = new S3Client([
'profile' => 'default',
'region' => 'us-east-1',
'version' => '2006-03-01'
]);
$result = $s3Client->putObject([
'Bucket' => 'awesomecatpictures',
'Key' => 'catsinhats/whitecats/white_cat_in_hat1.png',
'SourceFile' => '/tmp/asdf1234'
]);
Run Code Online (Sandbox Code Playgroud)
我相信正在发生的是该Bucket名称现在正在被 URL 编码。在进一步检查我从 SDK 收到的确切消息后,我发现了这一点:
执行PutObject时出错https://s3.amazonaws.com/awesomecatpictures%2Fcatsinhats/whitecats/white_cat_in_hat1.png
AWS HTTP 错误:客户端错误:
PUT https://s3.amazonaws.com/awesomecatpictures%2Fcatsinhats/whitecats/white_cat_in_hat1.png导致403 Forbidden
这表明/I 提供给我的Bucket参数已经通过urlencode(),现在是%2F。
签名的工作方式相当复杂,但问题归结为存储桶和密钥用于生成加密签名。如果它们在调用客户端和 AWS 内不完全匹配,则请求将被拒绝并返回 403。错误消息确实指出了问题:
我们计算的请求签名与您提供的签名不匹配。检查您的密钥和签名方法。
所以,我Key错了,因为我Bucket错了。
在我的情况下,我s3.getSignedUrl('getObject')在需要使用时使用s3.getSignedUrl('putObject')(因为我使用 PUT 上传我的文件),这就是签名不匹配的原因。
小智 5
对于 Python 集 - signature_version s3v4
s3 = boto3.client(
's3',
aws_access_key_id='AKIAIO5FODNN7EXAMPLE',
aws_secret_access_key='ABCDEF+c2L7yXeGvUyrPgYsDnWRRC1AYEXAMPLE',
config=Config(signature_version='s3v4')
)
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
84068 次 |
| 最近记录: |