gpt4 book ai didi

php - 谷歌存储桶的签名 URL 与提供的签名不匹配

转载 作者:搜寻专家 更新时间:2023-10-31 20:37:29 25 4
gpt4 key购买 nike

我在使用 Google 存储时遇到了困难。

所以我正在尝试制作一个 signed url ,已经有了客户端 ID(这是一封电子邮件)和私钥(如 here 所述),所以:

第 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;
}

到目前为止一切顺利(我认为),回显输出看起来与示例相似,所以现在对字符串进行签名

第 2 步:signing the string最初我使用的是 openssl_public_encrypt,在四处搜索后发现 google-api-php-client 有 Google_Signer_P12(它实际上使用了 openssl_sign),所以方法看起来像:

function googleSignString($certificatePath, $stringToSign) {
return (new Google_Signer_P12(
file_get_contents($certificatePath),
'notasecret'
))->sign($stringToSign);
}

我不确定这是否正确签名,最终构建最终 url

第 3 步:building the URL

function googleBuildSignedUrl($serviceEmail, $file, $expiration, $signature) {
return "http://storage.googleapis.com{$file}"
. "?GoogleAccessId={$serviceEmail}"
. "&Expires={$expiration}"
. "&Signature=" . urlencode($signature);
}

但在浏览器中打开 URL 将检索:

<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>

我添加了一个 gist最终脚本更易于阅读

那么知道我做错了什么吗?

最佳答案

我找到了解决方案,我正在做的过期日期有一个错误:

$expiration = (new DateTime())->modify('+3h')->getTimestamp();

所以我将 h 更改为 hours 以便它现在可以正常工作,例如:

$expiration = (new DateTime())->modify('+3hours')->getTimestamp();

但这并没有完全解决它,实际缺少的部分是 Google_Signer_P12::sign() 要求它在 base64 上编码,这在 google 文档中指定:

Google Cloud Storage expects the Base64 encoded signature in its APIs.

但是我(错误地)虽然 Google_Signer_P12::sign() 已经这样做了,所以在我理解这是必需的之后,我将签名方法更改为:

function googleSignString($certificatePath, $stringToSign)
{
return base64_encode((new Google_Signer_P12(
file_get_contents($certificatePath),
'notasecret'
))->sign($stringToSign));
}

它现在正在工作!!!

我还更新了 gist对于任何想使用它的人:)

关于php - 谷歌存储桶的签名 URL 与提供的签名不匹配,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31536066/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com