How to generate Signed URL for google cloud storag

2019-04-15 16:11发布

The method i tried using was with openssl

$fp = fopen($key, 'r');  //open the PEM file
$priv_key = fread($fp,8192);
fclose($fp);
$pkeyid = openssl_get_privatekey($priv_key,"password");

openssl_sign($response["data_to_sign"], $signature, $pkeyid,'sha256');

$sign = base64_encode($signature)

Is this the correct Method to generate signature for signed urls in google?

4条回答
Explosion°爆炸
2楼-- · 2019-04-15 16:32

There's an example here that signs a URL for Google Cloud Storage using PHP: https://groups.google.com/forum/#!msg/google-api-php-client/jaRYDWdpteQ/xbNTLfDhUggJ

However - I note this is tagged with Google App Engine... If your code is running inside of Google App Engine, you should use the built-in App Identity service - (note this will only work once your application is deployed in production, not while running locally) - this means you will not need to download or handle any private keys:

require_once 'google/appengine/api/app_identity/AppIdentityService.php';

$sign_result = AppIdentityService::signForApp( $message );

You will need to make sure that the service account associated with the App Engine application is added to the team for the project that owns the Cloud Storage bucket.

查看更多
淡お忘
3楼-- · 2019-04-15 16:40

I use Google Cloud Storage PHP SDK, the manual part of scripts is quite simple and looks clean.

cloud-storage PHP SDK

Install package to your project by following this page on Packagist, then

function getSignedGcsUrl($objPath/* which is your target object path */, $duration = 50) 
{
    $storageClient = new StorageClient([
        'projectId' => /* your gcp projectId here */,
        'keyFilePath' => /* your gcp keyFilePath here */,
    ]);
    $bucket = $storageClient->bucket($objPath);
    $object = $bucket->object();
    $url = $object->signedUrl(new \DateTime('+ ' . $duration . ' seconds'));
    return $url;
}

laravel-google-cloud-storage (for Laravel)

Install and configurate superbalist/laravel-google-cloud-storage by following this page: on Github, then

public static function getSignedGcsUrl($objPath, $duration = 50)
{
    return Storage::disk('gcs'/* following your filesystem configuration */)
        ->getAdapter()
        ->getBucket()
        ->object($objPath)
        ->signedUrl(new \DateTime('+ ' . $duration . ' seconds'));
}
查看更多
beautiful°
4楼-- · 2019-04-15 16:44

One thing to note that I spent about two hours on:

The GoogleAccessId you pass into the URL is the Email Address in the "Certificate" section of the Google Cloud Console. It's not the OAuth Client ID with a string replacement as Google suggests in their documentation.

查看更多
Viruses.
5楼-- · 2019-04-15 16:49

I put all the answers together. This should work in out of the box project. If you have space in the paths, you will need to rawurlencode the individual components, not urlencode.

function signedGoogleStorageURL($bucketName, $resourcePath, $duration = 10, $method = 'GET')
{
    $expires = time() + $duration;
    $content_type = ($method == 'PUT') ? 'application/x-www-form-
    urlencoded' : '';
    $to_sign = ($method . "\n" .
                /* Content-MD5 */ "\n" .
                $content_type . "\n" .
                $expires . "\n" .
                "/" . $bucketName . $resourcePath);

    $sign_result = AppIdentityService::signForApp($to_sign);
    $signature = urlencode(base64_encode($sign_result['signature']));
    $email = AppIdentityService::getServiceAccountName();

    return ('https://storage.googleapis.com/' . $bucketName .
            $resourcePath .
            '?GoogleAccessId=' . $email .
            '&Expires=' . $expires .
            '&Signature=' . $signature);
}

$signedPath = signedGoogleStorageURL(AppIdentityService::getDefaultVersionHostname(), "/my_folder/my_file", 60);
查看更多
登录 后发表回答