我正在尝试在AWS lambda上使用Google的People API。由于API需要OAuth2,我试图在本地获取OAuth2代币,然后将其传输到AWS lambda:
我用此功能存储秘密:
from oauth2client.file import Storage
from oauth2client import client, tools
def get_credentials():
credential_path = os.path.join(SCRIPT_DIR, 'people-api-secret.json')
store = Storage(credential_path)
credentials = store.get()
if not credentials or credentials.invalid:
flow = client.flow_from_clientsecrets(CLIENT_SECRET_FILE, SCOPES)
flow.user_agent = APPLICATION_NAME
credentials = tools.run_flow(flow, store)
print('Storing credentials to ' + credential_path)
return credentials
然后,我使用无服务器框架将people-api-secret.json
转移到AWS lambda。但是,当我尝试将秘密加载到lambda上时,store.get()
返回None
。该文件确实在AWS上(os.path.isfile(credential_path)
返回True
)。
不可能在另一个计算机/IP地址上复制这些秘密?如果不是这样的话:如果不采用"完全壁炉的方式"(例如这里
update 发现这是lambda上的一个简单的"权限拒绝"错误:print(open(credential_path).read())
产生[Errno 13] Permission denied: '/var/task/people-api-secret.json'
。我猜这些变量应该放入环境中,而不是从文件中读取?
就像这样做一样,请使用秘密键上载JSON,然后执行此操作:
#import GoogleCredentials
from oauth2client.client import GoogleCredentials
credentials = GoogleCredentials.get_application_default()
service = discovery.build('people', 'v1', credentials=credentials,cache_discovery=False)
在您的lambda配置上集google_application_credentials作为环境变量键,而您的凭据JSON文件名作为值。
它适用于我使用Google API的所有Lambdas。
虽然给予正确的权限可能会起作用(根据汤姆·梅洛斯(Tom Melos)评论和这个github问题),我想将秘密放入环境变量中,因为这被描述为最佳实践。<<<<<<<<<<<<<</p>
首先,我需要一种获取令牌的方法,所以我运行了此(这需要文件client_secret.json
,您可以根据本指南从Google API控制台下载):
from oauth2client import client, tools
class MyStorage(client.Storage):
def locked_put(self, credentials):
print("="*70)
print("client_id: {}nclient_secret: {}nrefresh_token: {}".format(
credentials.client_id, credentials.client_secret, credentials.refresh_token))
print("="*70)
flow = client.flow_from_clientsecrets('client_secret.json', 'https://www.googleapis.com/auth/contacts.readonly')
flow.user_agent = 'my-user-agent'
storage = MyStorage()
tools.run_flow(flow, storage)
我在本指南之后放入环境中的三个字符串,然后能够做到这一点:
import os
from oauth2client import client
from apiclient import discovery
client_id = os.environ['GOOGLE_PEOPLE_CLIENT_ID']
client_secret = os.environ['GOOGLE_PEOPLE_CLIENT_SECRET']
refresh_token = os.environ['GOOGLE_PEOPLE_REFRESH_TOKEN']
credentials = client.GoogleCredentials(None,
client_id,
client_secret,
refresh_token,
None,
"https://accounts.google.com/o/oauth2/token",
'my-user-agent')
http = credentials.authorize(httplib2.Http())
service = discovery.build('people', 'v1', http=http,
discoveryServiceUrl='https://people.googleapis.com/$discovery/rest',
cache_discovery=False)
有关更多详细信息(我个人刚刚了解了OAuth2的基础知识),我在这里记录了这些请求中发生的情况以及为什么我们在这里需要refresh_token
。