简体   繁体   English

Oauth2在aws lambda上谷歌人api

[英]Oauth2 to google people api on aws lambda

I'm trying to use google's people api on aws lambda. 我正试图在aws lambda上使用谷歌的人api As the api requires oauth2 I tried to fetch the oauth2 token locally and then transfer it to aws lambda: 由于api需要oauth2,我尝试在本地获取oauth2令牌,然后将其传输到aws lambda:

I store the secrets with this function: 我用这个函数存储秘密:

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

Then I transfer people-api-secret.json to aws lambda using the serverless framework. 然后我使用无服务器框架将people-api-secret.json到aws lambda。 But when I try to load the secret on lambda, then store.get() returns None . 但是当我尝试在lambda上加载秘密时, store.get()返回None The file is really there on AWS ( os.path.isfile(credential_path) returns True ). 该文件确实存在于AWS上( os.path.isfile(credential_path)返回True )。

Is it not possible to copy those secrets on another computer/IP address? 是否无法将这些秘密复制到另一台计算机/ IP地址上? If not: what would the "minimal way" of getting this to work without doing the "full fledged way" described eg here 如果不是:如果不采用例如此处描述的“完全成熟的方式”,使这种方式起作用的“最小方式”是什么?

Update Found out that it's a simple "permission denied" error on lambda: print(open(credential_path).read()) yields [Errno 13] Permission denied: '/var/task/people-api-secret.json' . 更新发现它是lambda上的一个简单的“权限被拒绝”错误: print(open(credential_path).read())产生[Errno 13] Permission denied: '/var/task/people-api-secret.json' I guess those variables should be put into environment instead of being read from file? 我想这些变量应该放入环境而不是从文件中读取?

Upload your json with the secret key just as you're doing, then do this: 用你正在做的秘密密钥上传你的json,然后执行以下操作:

#import GoogleCredentials
from oauth2client.client import GoogleCredentials

credentials = GoogleCredentials.get_application_default()
service = discovery.build('people', 'v1', credentials=credentials,cache_discovery=False)

On your lambda configuration set GOOGLE_APPLICATION_CREDENTIALS as environment variable key and your credentials json file name as value. 在lambda配置中,将GOOGLE_APPLICATION_CREDENTIALS设置为环境变量键,将凭据json文件名设置为值。

It works on all my lambdas that use google api. 它适用于我使用google api的所有lambda。

While giving the right permissions would probably have worked (according to Tom Melos comment and this github issue ) I wanted to put the secret into an environment variable because this is described as best practice. 虽然提供正确的权限可能会有效(根据Tom Melos评论和这个github问题 )我想把秘密放入环境变量中,因为这被描述为最佳实践。

First I needed a way to get the token, so I ran this (that needs the file client_secret.json which you can download from the google api console following this guide ): 首先我需要一种获取令牌的方法,所以我运行了这个(需要文件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)

The resulting three strings I put into the environment following this guide and then was able to do this: 我在本指南之后输入的三个字符串然后能够执行此操作:

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)

For more details (personally I just learned the basics of Oauth2) I've documented here what happens in these requests and why we need the refresh_token here. 有关更多详细信息(我个人刚刚学习了Oauth2的基础知识)我已经在这里记录了这些请求中发生了什么,以及为什么我们需要这里的refresh_token

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM