Last active
June 19, 2016 11:46
-
-
Save mloureiro/14503293c3cb2191e2f6 to your computer and use it in GitHub Desktop.
Generate a Google Signed URL
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<? | |
/** | |
* Google Bucket GET file with signed string example | |
*/ | |
require_once("vendor/autoload.php"); | |
/* | |
* Helper Methods | |
*/ | |
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; | |
} | |
function googleSignString($p12FilePath, $string) | |
{ | |
$certs = []; | |
if (!openssl_pkcs12_read(file_get_contents($p12FilePath), $certs, 'notasecret')) | |
{ | |
echo "Unable to parse the p12 file. OpenSSL error: " . openssl_error_string(); exit(); | |
} | |
$RSAPrivateKey = openssl_pkey_get_private($certs["pkey"]); | |
$signed = ''; | |
if(!openssl_sign( $string, $signed, $RSAPrivateKey, 'sha256' )) | |
{ | |
error_log( 'openssl_sign failed!' ); | |
$signed = 'failed'; | |
} | |
else | |
{ | |
$signed = base64_encode($signed); | |
} | |
return $signed; | |
} | |
function googleBuildSignedUrl($serviceEmail, $file, $expiration, $signature) | |
{ | |
return "http://storage.googleapis.com{$file}" | |
. "?GoogleAccessId={$serviceEmail}" | |
. "&Expires={$expiration}" | |
. "&Signature=" . urlencode($signature); | |
} | |
/* | |
* Initialization | |
*/ | |
$serviceEmail = '<service-email>'; | |
$p12FilePath = 'keys/google.certificate.p12'; | |
$expiration = (new DateTime())->modify('+3hours')->getTimestamp(); | |
$bucket = 'example'; | |
$fileToGet = 'video.mp4'; | |
/* | |
* Building! | |
*/ | |
$file = "/{$bucket}/{$fileToGet}"; | |
$string = googleBuildConfigurationString('GET', $expiration, $file); | |
$signedString = googleSignString($p12FilePath, $string); | |
$signedUrl = googleBuildSignedUrl($serviceEmail, $file, $expiration, $signedString); | |
?> | |
<html> | |
<body> | |
<style>pre {background: #eee;}</style> | |
<h2>String</h2> | |
<pre><?= $string ?></pre> | |
<br> | |
<h2>Final Url</h2> | |
<pre><?= $signedUrl ?></pre> | |
<br> | |
<video controls> | |
<source src="<?= $signedUrl ?>" type="video/mp4"> | |
</video> | |
</body> | |
</html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Are you positive this works? I'm getting a 'SignatureDoesNotMatch' error.. And my although it looks like it signed the url and creates a correct signed string.
Edit: The problem seemed to be with the way the signString was constructed. It might be a problem isolated to me but sometimes i had one too few linebreaks between GET and the expire date :/. I resorted to build it myself