Google 后端 oAuth Python3?
Google backend oAuth with Python3?
我查询 Google Calendar 一个用 Python 2.7 编写的程序,在服务器到服务器模式下 (使用证书)。通常是这样的:
with open('mycertfromgoogleconsole.p12', 'rb') as f:
private_key = f.read()
credentials = oauth2client.client.SignedJwtAssertionCredentials(
'something@developer.gserviceaccount.com,
private_key,
'https://www.googleapis.com/auth/calendar.readonly',
sub='theaccounttoimpersonate@example.com'
)
http_auth = credentials.authorize(httplib2.Http())
service = apiclient.discovery.build('calendar', 'v3', http=http_auth)
我现在需要将脚本移植到 Python 3.4,但找不到支持 oAuth 后端版本的库(有几个似乎支持 Web 版本)。你知道有没有可用的? (理想情况下是直接替代品,但那将近乎奇迹)
我终于成功了,下面的代码遵循 Google API 文档,最后一个请求产生了上面文档 "Handling the response" 中提到的令牌数据
import requests
import jwt
import arrow
import OpenSSL.crypto
class GetToken(object):
"""
Get Google API token as documented at https://developers.google.com/identity/protocols/OAuth2ServiceAccount
"""
def __init__(self):
self.expires = 0
self.token = None
def gettoken(self):
now = arrow.now().timestamp
# is the token still valid and exists ? (within a 10 seconds margin)
if now < (self.expires - 10) and self.token:
return self.token
self.expires = now + 3600
claim = {
"iss": "dev_account_from_google_console@developer.gserviceaccount.com",
"scope": "https://www.googleapis.com/auth/calendar.readonly",
"aud": "https://www.googleapis.com/oauth2/v3/token",
"exp": now,
"iat": now,
"sub": "account_with_delegated_rights@example.com"
}
p12 = OpenSSL.crypto.load_pkcs12(open('certificate_from_google_api_console.p12', 'rb').read(), 'notasecret')
private_key = OpenSSL.crypto.dump_privatekey(OpenSSL.crypto.FILETYPE_PEM, p12.get_privatekey()).decode('utf-8')
myjwt = jwt.encode(claim, private_key, algorithm='RS256', headers={"alg": "RS256", "typ": "JWT"}).decode('utf-8')
data = {
"grant_type": "urn:ietf:params:oauth:grant-type:jwt-bearer",
"assertion": myjwt
}
headers = {"Content-Type": "application/x-www-form-urlencoded"}
r = requests.post("https://www.googleapis.com/oauth2/v3/token", data=data, headers=headers)
print(r.json())
if __name__ == "__main__":
t = GetToken()
t.gettoken()
我查询 Google Calendar 一个用 Python 2.7 编写的程序,在服务器到服务器模式下 (使用证书)。通常是这样的:
with open('mycertfromgoogleconsole.p12', 'rb') as f:
private_key = f.read()
credentials = oauth2client.client.SignedJwtAssertionCredentials(
'something@developer.gserviceaccount.com,
private_key,
'https://www.googleapis.com/auth/calendar.readonly',
sub='theaccounttoimpersonate@example.com'
)
http_auth = credentials.authorize(httplib2.Http())
service = apiclient.discovery.build('calendar', 'v3', http=http_auth)
我现在需要将脚本移植到 Python 3.4,但找不到支持 oAuth 后端版本的库(有几个似乎支持 Web 版本)。你知道有没有可用的? (理想情况下是直接替代品,但那将近乎奇迹)
我终于成功了,下面的代码遵循 Google API 文档,最后一个请求产生了上面文档 "Handling the response" 中提到的令牌数据
import requests
import jwt
import arrow
import OpenSSL.crypto
class GetToken(object):
"""
Get Google API token as documented at https://developers.google.com/identity/protocols/OAuth2ServiceAccount
"""
def __init__(self):
self.expires = 0
self.token = None
def gettoken(self):
now = arrow.now().timestamp
# is the token still valid and exists ? (within a 10 seconds margin)
if now < (self.expires - 10) and self.token:
return self.token
self.expires = now + 3600
claim = {
"iss": "dev_account_from_google_console@developer.gserviceaccount.com",
"scope": "https://www.googleapis.com/auth/calendar.readonly",
"aud": "https://www.googleapis.com/oauth2/v3/token",
"exp": now,
"iat": now,
"sub": "account_with_delegated_rights@example.com"
}
p12 = OpenSSL.crypto.load_pkcs12(open('certificate_from_google_api_console.p12', 'rb').read(), 'notasecret')
private_key = OpenSSL.crypto.dump_privatekey(OpenSSL.crypto.FILETYPE_PEM, p12.get_privatekey()).decode('utf-8')
myjwt = jwt.encode(claim, private_key, algorithm='RS256', headers={"alg": "RS256", "typ": "JWT"}).decode('utf-8')
data = {
"grant_type": "urn:ietf:params:oauth:grant-type:jwt-bearer",
"assertion": myjwt
}
headers = {"Content-Type": "application/x-www-form-urlencoded"}
r = requests.post("https://www.googleapis.com/oauth2/v3/token", data=data, headers=headers)
print(r.json())
if __name__ == "__main__":
t = GetToken()
t.gettoken()