2017-01-31 25 views
1

我在一個小例子運行此代碼:未經授權的錯誤在GAE SDK,但它的作品一旦部署

from google.cloud import storage 
from google.appengine.api import app_identity 

class TestB(base_handler.TRNHandler): 
    #... 
    def post(self): 
     client = storage.Client() 
     bucket_name = os.environ.get('BUCKET_NAME', 
          app_identity.get_default_gcs_bucket_name()) 
     bucket = client.get_bucket(bucket_name) 
     #... 

如果我部署此代碼一切正常。但是,當我在本地運行它(SDK)時,出現錯誤:未經授權:401無效憑證。發生了什麼,我該如何解決它?

回答

2

我有一個非常強烈的猜測,雖然我不能確定沒有看到你的確切日誌和whatnot。

google.cloud庫對於授權非常聰明。它使用稱爲「應用程序默認憑據」的東西。如果您在App Engine或GCE實例上運行該代碼,代碼將能夠確定哪個服務帳戶與該實例相關聯,並使用該帳戶的憑證授權自己。

但是,當您在本地運行程序時,庫無法知道要使用哪些憑據,因此它只是匿名撥打電話。你可能水桶沒有授予匿名用戶訪問(這是好的),所以調用失敗有401

你可以,但是,本地與gcloud指令寄存器憑據:

$> gcloud auth application-default login 

運行那麼,圖書館將使用您用來登錄一段時間的任何憑據。或者,您還可以確保環境變量GOOGLE_APPLICATION_CREDENTIALS指向服務帳戶的JSON密鑰文件。

有很多關於Application Default Credentials選擇憑證的文檔。

或者,如果你願意在程序中指定AUTH權,you can do that too

storage = Storage.from_service_account_json('/path/to/key_file.json') 
+0

我嘗試使用gcloud指令,但我還是得到了未經授權的錯誤。我還添加了:env_variables: GOOGLE_APPLICATION_CREDENTIALS:secrets/trn-test2-fc647b4d3b1a.json,但它只將錯誤更改爲403調用方沒有storage.buckets.get存取bucket app_default_bucket。與最後一種方法相同的結果。也許還有另一個問題? –

+0

這是進步,不管你信不信。 403表示您的電話已成功通過身份驗證,但該帳號沒有權限。字符串「app_default_bucket」很有意思,請考慮一下 –

+0

好的,這是我的新理論。在開發服務器本地運行時,調用「get_default_gcs_bucket_name()」會返回一個常量字符串「app_default_bucket」,而不是您的GCS應用程序引擎存儲桶的實際名稱。這個想法是,你會寫一個本地假的GCS版本進行測試。但是你正在使用的圖書館確實做了應用程序引擎贗品;它會嘗試聯繫真正的GCS,並且沒有真正的存儲桶「app_default_bucket」可以訪問。我建議用正確的桶名稱替換函數調用。 –