我正在开发一个小型Web应用程序,以帮助我管理我的Gmail。我已使用通过django-allauth
收到的OAuth令牌通过Google的API使用以下功能对其进行了设置。
import google.oauth2.credentials
from .choices import GMAIL
from allauth.socialaccount.models import SocialToken, SocialAccount
from apiclient.discovery import build
def get_credentials(user):
account = SocialAccount.objects.get(user=user.id)
token = SocialToken.objects.get(app=GMAIL, account=account).token
credentials = google.oauth2.credentials.Credentials(token)
service = build('gmail', 'v1', credentials=credentials)
return service
这似乎有时可行,但是不幸的是,它不是很可靠。它在build()
函数中经常超时,只有大约三分之一的时间成功。我想知道是什么原因导致这种行为,以及是否有更可靠的方法来访问API?
我从these docs找到了以下AuthorizedSession
类:
from google.auth.transport.requests import AuthorizedSession
authed_session = AuthorizedSession(credentials)
response = authed_session.request(
'GET', 'https://www.googleapis.com/storage/v1/b')
但是我不知道如何将其转换为与Google API兼容的对象:
def get_labels(user):
service = get_credentials(user)
results = service.users().labels().list(userId='me').execute()
labels = results.get('labels', [])
return labels
不幸的是,Google's docs建议使用我希望避免使用的已弃用的软件包。
这是我第一次真正使用OAuth强制执行的API。有人有什么建议吗?
编辑:我尝试从Macbook发布。我也在Windows机器上尝试了该命令,在该机器上它的工作更加一致,但是每次执行build()
大约需要20秒。我觉得我做错了。
答案 0 :(得分:0)
在我终于将刷新令牌添加到组合中之后,今天上午的工作情况要好得多。也许缺席在另一端引起了一些问题。我将继续测试,但现在一切正常:
这是我的完整解决方案:
import google.oauth2.credentials
from google.auth.transport.requests import Request
from apiclient import errors, discovery
from myproject.settings import GMAIL_CLIENT_API_KEY, GMAIL_CLIENT_API_SECRET
def get_credentials(user):
token_set = user.socialaccount_set.first().socialtoken_set.first()
token = token_set.token
refresh_token = token_set.token_secret
credentials = google.oauth2.credentials.Credentials(
token,
refresh_token=refresh_token,
client_id=GMAIL_CLIENT_API_KEY,
client_secret=GMAIL_CLIENT_API_SECRET,
token_uri= google.oauth2.credentials._GOOGLE_OAUTH2_TOKEN_ENDPOINT,
)
if credentials.expired:
request = Request()
credentials.refresh(request)
service = discovery.build('gmail', 'v1', credentials=credentials)
return service
如您所见,我将我的API密钥添加到了设置文件中,并在此处引用了它们。昨天在源文件中打听时,我偶然发现了token_uri
。 refresh_token
是花费时间最长的作品。
好消息是django-allauth将把刷新令牌保存到SocialToken
列下的token_secret
模型中。但是,只有在您的设置中有以下内容时,它才会这样做:
SOCIALACCOUNT_PROVIDERS = {
'google': {
'SCOPE': [
'profile',
'email',
'https://www.googleapis.com/auth/gmail.labels',
'https://www.googleapis.com/auth/gmail.modify'
],
'AUTH_PARAMS': {
'access_type': 'offline',
}
}
}
具体地说,必须将access_type
中的AUTH_PARAMS
设置为'offline'
according to the docs。
现在,如果在实施此更改之前连接了帐户,仍然会给您带来麻烦,因此,您还需要通过Google permissions撤消对应用程序的访问权限以获得新的刷新令牌。有关更多信息,请参见in this question。
我不确定这是否是正确的/预期的方法,但是直到Google更新Django的文档之前,这种方法至少应该用于测试目的。