Ответ 1
Глядя на источник для JWT library, первое, что выпрыгивает на меня, и я вижу, что в комментариях было отмечено, что ваша полезная нагрузка должна быть массивом или объектом, а не строкой... " JSON веб-маркеры".
* @param object|array $payload PHP object or array
public static function encode($payload, $key, $alg = 'HS256', $keyId = null, $head = null)
Во-вторых, похоже, что вы оба кодируете base64... base128?:)
Возвращаемое значение encode
должно быть тремя конкретизированными строками Base64 url, поэтому вам не нужно будет делать это снова.
Я бы попробовал:
$payload = ['HTTP_Verb' => $method,
'Content_MD5' => $contentMd5,
'Content_Type' => $contentType,
'Expiration' => $expiration,
'Canonicalized_Resource' => $file];
$key = file_get_contents($credentialsFilePath);
$signedURL = Firebase\JWT\JWT::encode($payload, $key); //think base64_encode here is redundant.
Ссылка: Обзор страницы с подписанными URL. Они уверены, что не очень хорошо разбираются в этих документах. Я предполагаю, что вы посмотрели SDK?
Если вы хотите перейти по строковому маршруту, вам нужно будет подписать с помощью RSA-подписи с SHA256... opensssl_sign
, а также, может быть, проще опираться на Google PHP SDK?
Позже...
ОК, решил проверить его. У Google Cloud была бесплатная пробная версия. Установленный gsutil
, прочитайте кучу документов. Проклятый, если я понимаю этот подход JWT. Поделитесь, если кто-то может даже предоставить документы по этой теме.
Этот код работает:
<?php
$method = 'GET';
$expires = '1503532674';
$container = '/example-bucket/cat.jpeg';
$payload = "{$method}\n\n\n{$expires}\n{$container}";
//assume you have this 'json' formatted key too? Otherwise just load the private key file as is.
$key = file_get_contents('~/oas_private_key.json');
$key = json_decode($key, true);
$key = $key['private_key'];
//if sucessful the encypted string is assigned to $signature
openssl_sign($payload, $signature, $key, OPENSSL_ALGO_SHA256);
$signature = urlencode(base64_encode($signature));
die("https://storage.googleapis.com/{$container}[email protected]&Expires={$expires}&Signature={$signature}");
Наконец, ошибка "SignatureDoesNotMatch"! Лично я использовал SDK. Немного инициализации, и вы можете просто сделать что-то вроде следующего:
$url = $object->signedUrl(new Timestamp(new DateTime('tomorrow')), [
'method' => 'PUT'
]);
Это также облегчит обновление в будущем.