gpt4 book ai didi

python - 在独立的 Python 脚本中向 Google 进行身份验证的正确机制是什么?

转载 作者:太空宇宙 更新时间:2023-11-03 15:07:55 29 4
gpt4 key购买 nike

我有一些代码可以用来将 Gmail 联系人中的电子邮件地址提取到文本文件中。这是一个在 cron 作业中运行的简单 Python 脚本,并且基于 Python gdata library (目前 v2.0.18)。

截至本月早些时候,由于 Google deprecating the ClientLogin protocol,这不再有效.产生的错误如下所示:

{'status': 401, 'body': '<?xml version="1.0" encoding="UTF-8"?>\n<errors xmlns="http://schemas.google.com/g/2005">\n <error>\n  <domain>GData</domain>\n  <code>required</code>\n  <location type="header">Authorization</location>\n  <internalReason>Login Required</internalReason>\n </error>\n</errors>\n', 'reason': 'Unauthorized'}

我知道这会发生并在其他地方处理它(比如 AppEngine 应用程序),但忘记了我必须转换这个脚本。现在我来到这里,我发现我不知道我应该如何完成这项工作。

我找到的所有引用文献,例如 here在 Google Apps 开发者博客上或 herehere在 StackOverflow 上,建议解决方案是使用 OAuth2Token。但是,这需要来自 Google API 控制台的客户端 ID 和客户端密码——这与应用程序相关联。我没有申请。我只想通过我的脚本进行身份验证。

有人可以建议在独立脚本中执行此操作的正确方法吗?还是我运气不好,没有机制可以完成此任务?

这是现有联系人代码的核心:

from gdata.contacts.service import ContactsService, ContactsQuery

user = "myuser@gmail.com"
password = "mypassword"

addresses = set()
client = ContactsService(additional_headers={"GData-Version":"2"})
client.ssl = True
client.ClientLogin(user, password)
groups = client.GetGroupsFeed()
for group in groups.entry:
if group.content.text == "System Group: My Contacts":
query = ContactsQuery()
query.max_results = 9999 # large enough that we'll get "everything"
query.group = group.id.text
contacts = client.GetContactsFeed(query.ToUri())
for contact in contacts.entry:
for email in contact.email:
addresses.add(email.address.lower())
break
return addresses

理想情况下,我希望将 client.ClientLogin() 替换为使用 gdata 保留其余代码的其他机制。或者,如果这不能真正用 gdata 完成,我愿意转换到其他提供类似功能的库。

最佳答案

最终,使用 curl 组合一个 shell 脚本比使用 curl 更容易弄乱 gdata 库。正如预期的那样,我能够完成大部分在脚本之外手动验证过程 OAuth2 Device Flow instructions .

完成验证过程后,我获得了 4 个必需的凭据:客户端 ID、客户端密码、访问 token 和刷新 token 。根据 Google 的文档,访问 token 最终会过期。你可以通过要求 token 管理器刷新 token 来获取新的访问 token 。当您这样做时,您显然会得到一个新的访问 token ,但不是一个新的刷新 token 。

我将客户端 ID 和密码以及刷新 token 存储在 CREDENTIALS 中JSON 格式的文件。由于访问 token 随时间变化,因此它存储在 ACCESS 文件中,也是 JSON 格式。

脚本的重要部分如下所示:

#!/bin/ksh

CLIENT_ID=$(cat ${CREDENTIALS} | jq -r ".client_id")
CLIENT_SECRET=$(cat ${CREDENTIALS} | jq -r ".client_secret")
REFRESH_TOKEN=$(cat ${CREDENTIALS} | jq -r ".refresh_token")
ACCESS_TOKEN=$(cat ${ACCESS} | jq -r ".access_token")

CONTACTS_URL="https://www.google.com/m8/feeds/contacts/default/full?access_token=${ACCESS_TOKEN}&max-results=5000&v=3.0"
ERROR=$(curl --show-error --silent --fail "${CONTACTS_URL}" -o ${CONTACTS_XML} 2>&1)
RESULT=$?
if [[ ${RESULT} -eq 0 ]]
then
cat ${CONTACTS_XML} | grep 'gd:email' | sed 's/^.*address="//g' | sed 's/".*$//g' | tr '[:upper:]' '[:lower:]' | sort | uniq
elif [[ ${RESULT} -eq 22 ]]
then
echo "${ERROR}" | grep -q "401"
if [[ $? -eq 0 ]]
then
TOKEN_URL="https://www.googleapis.com/oauth2/v3/token"
REFRESH_PARAMS="client_id=${CLIENT_ID}&client_secret=${CLIENT_SECRET}&refresh_token=${REFRESH_TOKEN}&grant_type=refresh_token"
ERROR=$(curl --show-error --silent --fail --data "${REFRESH_PARAMS}" ${TOKEN_URL} -o ${REFRESH_JSON})
RESULT=$?
if [[ ${RESULT} -eq 0 ]]
then
ACCESS_TOKEN=$(cat ${REFRESH_JSON} | jq -r ".access_token")
jq -n --arg access_token "${ACCESS_TOKEN}" '{"access_token": $access_token, }' > ${ACCESS}

CONTACTS_URL="https://www.google.com/m8/feeds/contacts/default/full?access_token=${ACCESS_TOKEN}&max-results=5000&v=3.0"
ERROR=$(curl --show-error --silent --fail "${CONTACTS_URL}" -o ${CONTACTS_XML} 2>&1)
RESULT=$?
if [[ ${RESULT} -eq 0 ]]
then
cat ${CONTACTS_XML} | grep 'gd:email' | sed 's/^.*address="//g' | sed 's/".*$//g' | tr '[:upper:]' '[:lower:]' | sort | uniq
else
print "Unexpected error: ${ERROR}" >&2
exit 1
fi
else
print "Unexpected error: ${ERROR}" >&2
exit 1
fi
else
print "Unexpected error: ${ERROR}" >&2
exit 1
fi
else
print "Unexpected error: ${ERROR}" >&2
exit 1
fi

这不是世界上最漂亮的东西,但我一直在寻找一些快速而肮脏的东西,这很管用。

关于python - 在独立的 Python 脚本中向 Google 进行身份验证的正确机制是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30624414/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com