Signed URL for google bucket does not match signature provided(谷歌存储桶的签名 URL 与提供的签名不匹配)
问题描述
I'm having an hard time working with google storage.
So I'm trying to make a signed url, already have the client id (which is an email) and private key (as described here) so:
STEP 1: construct the string
function googleBuildConfigurationString($method, $expiration, $file, array $options = []) {
$allowedMethods = ['GET', 'HEAD', 'PUT', 'DELETE'];
// initialize
$method = strtoupper($method);
$contentType = $options['Content_Type'];
$contentMd5 = $options['Content_MD5'] ? base64_encode($options['Content_MD5']) : '';
$headers = $options['Canonicalized_Extension_Headers'] ? $options['Canonicalized_Extension_Headers'] . PHP_EOL : '';
$file = $file ? $file : $options['Canonicalized_Resource'];
// validate
if(array_search($method, $allowedMethods) === false) {
throw new RuntimeException("Method '{$method}' is not allowed");
}
if(!$expiration) {
throw new RuntimeException("An expiration date should be provided.");
}
return <<<TXT
{$method}
{$contentMd5}
{$contentType}
{$expiration}
{$headers}{$file}
TXT;
}
So far so good (I think), echoing the output it looks similar to the examples, so now to sign the string
STEP 2: signing the string Initialy I was using openssl_public_encrypt, after searching around found that google-api-php-client has the Google_Signer_P12 (which actually uses openssl_sign), so the method looks like:
function googleSignString($certificatePath, $stringToSign) {
return (new Google_Signer_P12(
file_get_contents($certificatePath),
'notasecret'
))->sign($stringToSign);
}
And here I'm not sure if this is signing it correctly, finally building final url
STEP 3: building the URL
function googleBuildSignedUrl($serviceEmail, $file, $expiration, $signature) {
return "http://storage.googleapis.com{$file}"
. "?GoogleAccessId={$serviceEmail}"
. "&Expires={$expiration}"
. "&Signature=" . urlencode($signature);
}
But the opening the URL in the browser will retrieve:
<Error>
<Code>SignatureDoesNotMatch</Code>
<Message>
The request signature we calculated does not match the signature you provided. Check your Google secret key and signing method.
</Message>
<StringToSign>GET 1437470250 /example/video.mp4</StringToSign>
</Error>
I've added a gist with the final script to be easier to read
So any idea what am I doing wrong?
I've found the solution, there was a bug on the expiration date where I was doing:
$expiration = (new DateTime())->modify('+3h')->getTimestamp();
So I've changed h
to hours
so that it works now, like:
$expiration = (new DateTime())->modify('+3hours')->getTimestamp();
But that didn't quite solved it, the actual missing part is that the Google_Signer_P12::sign()
requires it to be encoded on base64, which is specified on the google docs:
Google Cloud Storage expects the Base64 encoded signature in its APIs.
However I (wrongly) though that Google_Signer_P12::sign()
already would do that, so after I understood that it was required I've changed the sign method to:
function googleSignString($certificatePath, $stringToSign)
{
return base64_encode((new Google_Signer_P12(
file_get_contents($certificatePath),
'notasecret'
))->sign($stringToSign));
}
And it is working now!!!
I've also updated the gist for anyone that wants to use it :)
这篇关于谷歌存储桶的签名 URL 与提供的签名不匹配的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本文标题为:谷歌存储桶的签名 URL 与提供的签名不匹配


基础教程推荐
- 如何在 Laravel 中使用 React Router? 2022-01-01
- PHP PDO MySQL 查询 LIKE ->多个关键词 2021-01-01
- Cron Jobs 调用带有变量的 PHP 脚本 2022-01-01
- YouTube API v3 点赞视频,但计数器不增加 2022-01-01
- PHP 类:全局变量作为类中的属性 2021-01-01
- 有什么方法可以用编码 UTF-8 而不是 Unicode 返回 PHP`json_encode`? 2021-01-01
- 如何在 Laravel 5.3 注册中添加动态下拉列表列? 2021-01-01
- 在PHP中根据W3C规范Unicode 2022-01-01
- 学说 dbal querybuilder 作为准备好的语句 2022-01-01
- 如何替换eregi() 2022-01-01