Google Cloud Storage Signed URLs — The Easy Way

SimpleBackups founder

Laurent Lemaire

Co-founder, SimpleBackups

November 3, 2018

One of the cool things that Google Cloud Storage supports is the AWS S3 interoperability mode. This mode allows you to use almost the same API used for AWS S3 to deal with Google Cloud Storage including authentication.

It relies on the same variables needed for S3:

  • Access Key
  • Secret Key
  • Bucket
  • Region

Google Cloud Storage Signed URLs

While pretty much of the operations work fine in an S3-like way, signing URLs won’t, since Google uses a different URL signing method. This becomes problematic if you want to use Google Cloud Storage as a Laravel filesystem using the S3 driver.

I am going to show how you can create a signed URL using a PHP function that has no dependencies, no service account needed, and no key file.

Creating a signed download URL

<?php

$filepath = 'path/to/file.tar.gz'; // do not include the bucket name, no slash in the beginning
$bucket = 'my-bucket-name';
$key = 'GOOGSOMEKEYHERE'; // key
$secret = 'aNdTHEsecretGoesRitghtHere'; // secret

function getSignedGoogleCloudStorageUrl($filepath, $bucket, $secret, $key, $duration = 50)
{
    $expires = new DateTime('+ ' . $duration . ' seconds');
    $seconds = $expires->format('U');

    $objectPieces = explode('/', $filepath);
    array_walk($objectPieces, function (&$piece) {
        $piece = rawurlencode($piece);
    });
    $objectName = implode('/', $objectPieces);

    $resource = sprintf(
        '/%s/%s',
        $bucket,
        $objectName
    );

    $headers = []; // you may add any headers needed here

    $toBeSignedArray = [
        'GET',
        '', // contentMd5, can be left blank
        '', // contentType, can be left blank
        $seconds,
        implode("n", $headers) . $resource,
    ];

    $toBeSignedString = implode("n", $toBeSignedArray);
    $encodedSignature = urlencode(base64_encode(hash_hmac('sha1', $toBeSignedString, $secret, true)));

    $query   = [];
    $query[] = 'GoogleAccessId=' . $key;
    $query[] = 'Expires=' . $seconds;
    $query[] = 'Signature=' . $encodedSignature;

    return "https://storage.googleapis.com/{$bucket}/{$filepath}?" . implode('&', $query);
}

This is the same signing function used by Google’s PHP SDK but simplified to only support the GET method for file downloads. Additionally, it utilizes the hidden fact that you can replace the GoogleAccessId with the Key and use theSecret Key to sign the payload.

You can create a free SimpleBackups account and effortlessly back up your databases, servers and websites with the ability to choose Google Cloud Storage and other providers as a storage option! Try it out.



Back to blog

Stop worrying about your backups.
Focus on building amazing things!

Free 7-day trial. No credit card required.

Have a question? Need help getting started?
Get in touch via chat or at [email protected]

Customer support with experts
Security & compliance
Service that you'll love using