Oauth2 to google people api on aws lambda

时间:2017-12-27 10:20:57

标签: python python-3.x oauth-2.0 aws-lambda serverless-framework

我正在尝试在aws lambda上使用google's 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地址上?如果不是:如果没有采用例如所描述的“完全成熟的方式”,那么使其工作的“最小方式”是什么? here

更新在lambda上发现这是一个简单的“权限被拒绝”错误:print(open(credential_path).read())会产生[Errno 13] Permission denied: '/var/task/people-api-secret.json'。我想这些变量应该放入环境而不是从文件中读取?

2 个答案:

答案 0 :(得分:3)

使用密钥上传您的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的lambda。

答案 1 :(得分:0)

虽然提供正确的权限可能会有效(根据Tom Melos评论和this github issue)我想把秘密放入环境变量中,因为这被描述为最佳实践。

首先我需要一种方法来获取令牌,所以我运行了这个(需要文件client_secret.json,您可以在this guide之后从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)

我在this guide之后放入环境中得到的三个字符串然后能够执行此操作:

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的基础知识)我documented here这些请求中发生了什么以及为什么我们需要refresh_token