5

我覺得在這裏發佈這個很奇怪,但因爲SO是Google API支持的唯一官方渠道,所以我想我需要在這裏提問。爲什麼Google Storage API不能與Amazon SDK v3一起使用?

如果你有API,工具的使用,或其他軟件開發相關的 問題,搜索和發佈問題上堆棧溢出,使用 官方谷歌雲存儲標籤。

好吧,所以這裏。我花了兩天的精力在嘗試讓Google Storage在亞馬遜PHP SDK的v3版本(最新版本)上工作。我無法使用較舊版本的SDK,因爲我試圖堅持使用Laravel 5.1的文件系統,而無需爲Google Storage編寫全新的驅動程序。我相信這是一個什麼樣谷歌發佈了谷歌存儲的精神內:

https://cloud.google.com/storage/docs/migrating

在從Amazon S3到谷歌雲存儲的簡單遷移,您可以 使用現有的工具和庫用於生成已認證的 對Amazon S3的REST請求,還將已驗證的請求發送至 Google雲端存儲。本部分描述了您需要對現有的 工具和庫進行的更改。

若要設立一個簡單的遷移執行以下操作:

設置默認的谷歌項目。

獲取開發人員密鑰。

在您現有的工具或庫中,進行以下更改:將請求 端點更改爲使用Google Cloud Storage請求端點。將 Amazon Web Services(AWS)訪問和密鑰替換爲相應的 Google Cloud Storage訪問密鑰和密鑰(統稱爲 您的Google開發人員密鑰)。

就是這樣!此時,您可以使用現有工具和庫開始 向Google雲端存儲發送keyed-hash消息 認證碼(HMAC)請求。

什麼樣的音調!讓我們嘗試使用使用gsutil的互操作性憑證。

$client = new S3Client([ 
    'credentials' => [ 
     'key' => 'GOOGxxxxxxxxxxxxxxx', 
     'secret' => 'ZfcOTxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx', 
    ], 
    'region' => 'US', 
    'version' => 'latest', 
    'endpoint' => 'https://storage.googleapis.com', 
]); 

try { 
    $result = $client->putObject(array(
     'Bucket' => 'devtest', 
     'Key' => 'test', 
     'Body' => 'Hello world' 
    )); 

    echo $result['ObjectURL']; 
} catch (\Aws\S3\Exception\S3Exception $e) { 
    // The AWS error code (e.g.,) 
    echo $e->getAwsErrorCode() . "\n"; 
    // The bucket couldn't be created 
    echo $e->getMessage() . "\n"; 
} 

不起作用。您會收到「錯誤的身份驗證標題」。我們來看看這個標題。

AWS4-HMAC-SHA256 憑證= GOOGGUxxxxxxxxxxx/20150611/US/S3/aws4_request, SignedHeaders =主機; X-AMZ-內容-SHA256; X-AMZ-日期, 簽名= 9c7de4xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

我在這裏創建了一個關於此的SO帖子,有人建議我添加'signature'=>'v2'。

Google Storage Incorrect Authorization Header with Amazon S3 PHP SDK v3

讓我們試試:

$client = new S3Client([ 
    'credentials' => [ 
     'key' => 'GOOGxxxxxxxxxxxxxxx', 
     'secret' => 'ZfcOTxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx', 
    ], 
    'region' => 'US', 
    'version' => 'latest', 
    'endpoint' => 'https://storage.googleapis.com', 
    'signature' => 'v2', 
]); 

沒有運氣。同樣的錯誤。授權標頭沒有改變。讓我們看看S3Client的代碼,看看如何使用「簽名」:

public function createPresignedRequest(CommandInterface $command, $expires) 
{ 
    /** @var \Aws\Signature\SignatureInterface $signer */ 
    $signer = call_user_func(
     $this->getSignatureProvider(), 
     $this->getConfig('signature_version'), 
     $this->getApi()->getSigningName(), 
     $this->getRegion() 
    ); 

    return $signer->presign(
     \Aws\serialize($command), 
     $this->getCredentials()->wait(), 
     $expires 
    ); 
} 

它沒有。所以,現在我們從S3的官方文檔偏離,因爲他們說同一件事:

http://docs.aws.amazon.com/aws-sdk-php/guide/latest/configuration.html

這不是「簽名」,這是「signature_version」。讓我們將其改爲v2。

$client = new S3Client([ 
    'credentials' => [ 
     'key' => 'GOOGxxxxxxxxxxxxxxx', 
     'secret' => 'ZfcOTxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx', 
    ], 
    'region' => 'US', 
    'version' => 'latest', 
    'endpoint' => 'https://storage.googleapis.com', 
    'signature_version' => 'v2', 
]); 

這次至少我們得到了一個不同的錯誤!

UnresolvedSignatureException在SignatureProvider.php線61:無法 解決的V2/S3/US簽名。有效簽名版本包括 v4和匿名。

因此,在玩了兩天之後,看起來這是不可能的,至少不會讓Google想讓你相信他們的音調。我根本無法得到這個工作,所以我希望這裏有人能夠闡明這一點。要麼我錯過了一些重要的事情,要麼谷歌虛假宣傳谷歌存儲使用亞馬遜的S3 SDK工作,並浪費開發者的時間。我在想,也許我們必須手動劫持授權頭,但那不在我的專業知識範圍之內。任何幫助將不勝感激。

+0

將'version'設置爲早於'latest',怎麼辦?沒有嘗試,只是在黑暗中拍攝。 – zaak

+0

@zaak是的,我也試過。沒有運氣。 – Citizen

+0

您可以比較gsutil auth頭文件(可以用「gsutil -D ...」查看)與PHP SDK發送的不同嗎? –

回答

3

因此,我打算髮布的時間比從未晚,並說我使用laravel 5.1,您必須在配置時選擇是否要使用AWS或GCS,因爲您無法進行配置安裝兩個版本的aws php客戶端(這限制你選擇的flysystem爲v2或v3,GCS需要v2,而laravel中的s3實現需要v3,我花了小時試圖讓v3與GCS協同工作,但認證標頭是不同的,所以我沒有理會。

你必須提供自己的供應商,但它並不難設置,只需在應用程序創建GcsAppsServiceProvider.php /供應商

<?php namespace App\Providers; 

use Illuminate\Support\ServiceProvider; 
use Storage; 
use Aws\S3\S3Client; 
use League\Flysystem\AwsS3v2\AwsS3Adapter; 
use League\Flysystem\Filesystem; 

class GcsAppsServiceProvider extends ServiceProvider 
{ 
    public function register() 
    { 

    } 

    public function boot() 
    { 
     Storage::extend('gcs', function($app, $config) 
     { 
      $client = S3Client::factory([ 
       'key' => $config['key'], 
       'secret' => $config['secret'], 
       'base_url' => $config['base_url'], 
      ]); 

      return new Filesystem(new AwsS3Adapter($client, $config['bucket'])); 
     }); 
    } 
} 

基本上在你的配置你只是複製S3配置在filesystem.php和不斷變化的區域 - > BASE_URL。您也可以自由將默認和雲更改爲gcs以支持谷歌雲存儲。

's3' => [ 
    'driver' => 's3', 
    'key' => env('AWS_KEY', 'your-key'), 
    'secret' => env('AWS_SECRET', 'your-secret'), 
    'region' => env('AWS_REGION','your-region'), 
    'bucket' => env('AWS_BUCKET','your-bucket'), 
], 

'gcs' => [ 
    'driver' => 'gcs', 
    'key' => env('GCS_KEY', 'your-key'), 
    'secret' => env('GCS_SECRET', 'your-secret'), 
    'base_url' => env('GCS_BASE_URL','your-base-url'), 
    'bucket' => env('GCS_BUCKET','your-bucket'), 
], 

最後但並非最不重要,你還需要將提供程序添加到提供者列表中app.php

'providers' => [ 
    ... 
    App\Providers\GcsAppsServiceProvider::class, 
], 

AWS的S3適配器還提到,GCS supports it in their documentation

相關問題