Gmail API with OAuth and Python - AccessTokenRefreshError: invalid_grant
Gmail API with OAuth and Python - AccessTokenRefreshError: invalid_grant
我正在尝试将 Gmail API 与 Python 客户端库一起使用。但是,我遇到了关于 AccessTokenRefreshError: invalid_grant
.
的错误消息
我已经安装了 Google 客户端库:
pip install google-api-python-client
我已转到 Google Developer's Console,创建了一个新项目,然后转到 APIs & auth,然后是 Credentials 。然后我点击了 创建新的客户端 ID,并选择了 服务帐户 。
起初,当我运行以下命令时,它抱怨没有加密库,所以我 pip 安装了 pycrypto。然后,它抱怨密钥文件格式错误,所以我 pip installed pyopenssl
然后,在 Python shell 我运行:
from oauth2client.client import SignedJwtAssertionCredentials
client_email = '<SANITISED>.apps.googleusercontent.com'
with open("foobar-d31647e3d00a.p12") as f:
private_key = f.read()
credentials = SignedJwtAssertionCredentials(client_email, private_key, 'https://www.googleapis.com/auth/gmail.readonly')
from httplib2 import Http
http_auth = credentials.authorize(Http())
from apiclient.discovery import build
gmail_server = build('gmail', 'v1', http=http_auth)
当我运行最后一条命令时,我得到了以下堆栈跟踪:
AccessTokenRefreshError Traceback (most recent call last)
<ipython-input-8-7fd72f40edd2> in <module>()
----> 1 gmail_server = build('gmail', 'v1', http=http_auth)
/Users/victorhooi/.virtualenvs/kenny/lib/python2.7/site-packages/oauth2client/util.pyc in positional_wrapper(*args, **kwargs)
133 else: # IGNORE
134 pass
--> 135 return wrapped(*args, **kwargs)
136 return positional_wrapper
137
/Users/victorhooi/.virtualenvs/kenny/lib/python2.7/site-packages/googleapiclient/discovery.pyc in build(serviceName, version, http, discoveryServiceUrl, developerKey, model, requestBuilder, credentials)
196 logger.info('URL being requested: GET %s' % requested_url)
197
--> 198 resp, content = http.request(requested_url)
199
200 if resp.status == 404:
/Users/victorhooi/.virtualenvs/kenny/lib/python2.7/site-packages/oauth2client/util.pyc in positional_wrapper(*args, **kwargs)
133 else: # IGNORE
134 pass
--> 135 return wrapped(*args, **kwargs)
136 return positional_wrapper
137
/Users/victorhooi/.virtualenvs/kenny/lib/python2.7/site-packages/oauth2client/client.pyc in new_request(uri, method, body, headers, redirections, connection_type)
528 if not self.access_token:
529 logger.info('Attempting refresh to obtain initial access_token')
--> 530 self._refresh(request_orig)
531
532 # Clone and modify the request headers to add the appropriate
/Users/victorhooi/.virtualenvs/kenny/lib/python2.7/site-packages/oauth2client/client.pyc in _refresh(self, http_request)
742 """
743 if not self.store:
--> 744 self._do_refresh_request(http_request)
745 else:
746 self.store.acquire_lock()
/Users/victorhooi/.virtualenvs/kenny/lib/python2.7/site-packages/oauth2client/client.pyc in _do_refresh_request(self, http_request)
805 except (TypeError, ValueError):
806 pass
--> 807 raise AccessTokenRefreshError(error_msg)
808
809 def _revoke(self, http_request):
AccessTokenRefreshError: invalid_grant
对我做错了什么有什么想法吗?
啊哈,我发现了问题 - 我的愚蠢行为。
我正在使用 "Client ID",并将其传递给 SignedJwtAssertionCredentials
我应该一直使用 "Email Address",而不是传递它。
你会认为变量被命名为 client_email
的事实会是一个线索......哈哈。
作为参考,相关 API 文档页面:
我正在尝试将 Gmail API 与 Python 客户端库一起使用。但是,我遇到了关于 AccessTokenRefreshError: invalid_grant
.
我已经安装了 Google 客户端库:
pip install google-api-python-client
我已转到 Google Developer's Console,创建了一个新项目,然后转到 APIs & auth,然后是 Credentials 。然后我点击了 创建新的客户端 ID,并选择了 服务帐户 。
起初,当我运行以下命令时,它抱怨没有加密库,所以我 pip 安装了 pycrypto。然后,它抱怨密钥文件格式错误,所以我 pip installed pyopenssl
然后,在 Python shell 我运行:
from oauth2client.client import SignedJwtAssertionCredentials
client_email = '<SANITISED>.apps.googleusercontent.com'
with open("foobar-d31647e3d00a.p12") as f:
private_key = f.read()
credentials = SignedJwtAssertionCredentials(client_email, private_key, 'https://www.googleapis.com/auth/gmail.readonly')
from httplib2 import Http
http_auth = credentials.authorize(Http())
from apiclient.discovery import build
gmail_server = build('gmail', 'v1', http=http_auth)
当我运行最后一条命令时,我得到了以下堆栈跟踪:
AccessTokenRefreshError Traceback (most recent call last)
<ipython-input-8-7fd72f40edd2> in <module>()
----> 1 gmail_server = build('gmail', 'v1', http=http_auth)
/Users/victorhooi/.virtualenvs/kenny/lib/python2.7/site-packages/oauth2client/util.pyc in positional_wrapper(*args, **kwargs)
133 else: # IGNORE
134 pass
--> 135 return wrapped(*args, **kwargs)
136 return positional_wrapper
137
/Users/victorhooi/.virtualenvs/kenny/lib/python2.7/site-packages/googleapiclient/discovery.pyc in build(serviceName, version, http, discoveryServiceUrl, developerKey, model, requestBuilder, credentials)
196 logger.info('URL being requested: GET %s' % requested_url)
197
--> 198 resp, content = http.request(requested_url)
199
200 if resp.status == 404:
/Users/victorhooi/.virtualenvs/kenny/lib/python2.7/site-packages/oauth2client/util.pyc in positional_wrapper(*args, **kwargs)
133 else: # IGNORE
134 pass
--> 135 return wrapped(*args, **kwargs)
136 return positional_wrapper
137
/Users/victorhooi/.virtualenvs/kenny/lib/python2.7/site-packages/oauth2client/client.pyc in new_request(uri, method, body, headers, redirections, connection_type)
528 if not self.access_token:
529 logger.info('Attempting refresh to obtain initial access_token')
--> 530 self._refresh(request_orig)
531
532 # Clone and modify the request headers to add the appropriate
/Users/victorhooi/.virtualenvs/kenny/lib/python2.7/site-packages/oauth2client/client.pyc in _refresh(self, http_request)
742 """
743 if not self.store:
--> 744 self._do_refresh_request(http_request)
745 else:
746 self.store.acquire_lock()
/Users/victorhooi/.virtualenvs/kenny/lib/python2.7/site-packages/oauth2client/client.pyc in _do_refresh_request(self, http_request)
805 except (TypeError, ValueError):
806 pass
--> 807 raise AccessTokenRefreshError(error_msg)
808
809 def _revoke(self, http_request):
AccessTokenRefreshError: invalid_grant
对我做错了什么有什么想法吗?
啊哈,我发现了问题 - 我的愚蠢行为。
我正在使用 "Client ID",并将其传递给 SignedJwtAssertionCredentials
我应该一直使用 "Email Address",而不是传递它。
你会认为变量被命名为 client_email
的事实会是一个线索......哈哈。
作为参考,相关 API 文档页面: