我正在尝试使用 Oauth2 通过无头 Linux 服务器访问 Google API 服务。我通读了这篇文章中的所有答案:如何在没有用户干预的情况下授权应用程序(网络或安装)?但他们都没有展示如何使用刷新令牌在python中生成访问令牌。 pinnoyyid 有一个 JavaScript 示例(https://stackoverflow.com/a/19766913/15713034),如下所示:
function get_access_token_using_saved_refresh_token() {
// from the oauth playgroundfunction get_access_token_using_saved_refresh_token() {
// from the oauth playground
const refresh_token = "1/0PvMAoF9GaJFqbNsLZQg-f9NXEljQclmRP4Gwfdo_0";
// from the API console
const client_id = "559798723558-amtjh114mvtpiqis80lkl3kdo4gfm5k.apps.googleusercontent.com";
// from the API console
const client_secret = "WnGC6KJ91H40mg6H9r1eF9L";
// from https://developers.google.com/identity/protocols/OAuth2WebServer#offline
const refresh_url = "https://www.googleapis.com/oauth2/v4/token";
let refresh_request = {
body:`grant_type=refresh_token&client_id=${encodeURIComponent(client_id)}&client_secret=${encodeURIComponent(client_secret)}& refresh_token=${encodeURIComponent(refresh_token)}`;,
method: "POST",
headers: new Headers({
'Content-Type': 'application/x-www-form-urlencoded'
})
}
JavaScript 并不是我最好的语言,但我可以破译他们正在向谷歌服务器发送 POST 请求。所以我尝试使用
requests
包在 Python 中重新创建请求:
import requests
result = requests.post("https://www.googleapis.com/oauth2/v4/token", body={'grant_type':'refresh-token', 'client_id':client_id, 'client_secret':client_secret, 'refresh_token': refresh_token}, headers={'Content-Type': 'application/x-www-form-urlencoded'})
当我查看结果时,它显示它有一个 200 状态代码(成功),但是当我尝试检查响应时,没有什么容易阅读的内容,并且我无法解析 JSON 中的结果以获取访问令牌。我尝试的另一种方法是使用 Google 建议的代码启动 Flask 服务器:https://developers.google.com/identity/protocols/oauth2/web-server#python_5 但这也不起作用,因为当我尝试从无论如何都不会返回 JSON 的函数(包含访问代码的对象)之一返回凭据。我更喜欢 post 请求方法,因为它更干净并且使用更少的代码。谢谢!
在 Python 中,一种方法是使用 requests-oauthlib 来执行后端应用程序流程。当您没有前端可以将某人重定向到以批准获取令牌时,这非常有用。
这个网站(https://community.atlassian.com/t5/Bitbucket-questions/Refresh-Tokens-using-Python-requests/qaq-p/1213162)说解决方案可能是这样的:
import requests
auth = ("<consumer_id>", "<consumer_secret>")
params = {
"grant_type":"refresh_token",
"refresh_token":"<your_refresh_token_here>"
}
url = "https://www.googleapis.com/oauth2/v4/token"
ret = requests.post(url, auth=auth, data=params) #note data=params, not params=params
由于上述解决方案均无效,我最终不得不放弃并使用服务帐户。
您可以查看这篇中等文章中的 Python 代码示例,为 Google OAuth 客户端生成刷新令牌。