我正在尝试使用signed URLs将文件从浏览器直接上传到GCS。我正在从App Engine标准PHP应用程序生成一个v4
签名的URL,看来工作正常。问题是,当我尝试PUT
到该URL时,我得到一个403
,具有以下XML响应:
<?xml version='1.0' encoding='UTF-8'?>
<Error>
<Code>AccessDenied</Code>
<Message>Access denied.</Message>
<Details>Anonymous caller does not have storage.objects.create access to <bucket-name>/some-object.txt.</Details>
</Error>
我的App Engine服务帐户具有Service Account Token Creator
,可用于创建URL。
我已启用存储桶中的CORS来接受PUT
至*
,这使我能够到达现在的位置。
我已经从v2
网址切换到v4
,因为Go SDK上的问题表明这是个问题。
我正在使用PHP Google Cloud Library生成签名URL,如下所示:
$storage = new StorageClient();
$bucket = $storage->bucket('<bucket-name>');
$object = $bucket->object('some-object.txt');
$url = $object->signedUploadUrl(new \DateTime('tomorrow'), ['version' => 'v4']);
我尝试将服务帐户添加到存储桶的权限中,并添加Storage Object Admin
,Storage Object Creator
等,但是似乎没有什么可以使我超越403
(除了打开它之外)到allUsers
)。
在this文章中说
此外,在Cloud Storage中,您需要授予以下权限才能生成签名URL。
storage.buckets.get
storage.objects.create
storage.objects.delete
但是我无法确定他们需要添加到哪个角色。
在这一点上,我认为存在两种可能性之一:
allUsers
显然是错误的)?已解决:
我的实现存在很多问题:
signedUploadUrl
不适合直接PUT
。为了解决这个问题,我需要使用beginSignedUploadSession
Storage Object Creator
。但是,它已经被添加到GAE默认服务帐户中,因为它是Project Editor
Service Account Token Creator
需要明确地添加到服务帐户,因为Project Editor
似乎没有涵盖该帐户。const url='{{ upload_url }}';
将URL嵌入到Javascript中,但是Twig自动对变量进行HTML编码,从而破坏了URL,相反,我需要使用{{ upload_url|raw }}
。这种格式损坏的原因是邮件中包含Anonymous caller
答案 0 :(得分:1)
signedUploadUrl
为POST HTTP方法创建URL(请参见https://github.com/googleapis/google-cloud-php/blob/master/Storage/src/StorageObject.php中的库源代码)。您正在使用该签名的URL进行PUT请求,因此不允许该请求。该错误消息并未将其显示为问题,但我认为这确实是问题所在。
您可以研究如何通过POST上传文件,也可以为PUT创建签名的URL。我已经在Python中完成了后者,但是我没有找到使用此库的方法。我不是PHP程序员,所以我可能会想念它。
或者,您可以创建自己的代码以创建用于PUT的签名URL,首先以库代码为例。签名的URL很难完全正确,创建自己的代码可能会令人沮丧。这是给我的Python语言。