【问题标题】:Accomplishing Oauth2.0 authorization with refresh token through Python (Google API service creation)通过Python使用刷新令牌完成Oauth2.0授权(谷歌API服务创建)
【发布时间】:2021-07-15 23:33:01
【问题描述】:

我正在尝试通过使用 Oauth2 的无头 Linux 服务器访问 Google API 服务。我阅读了这篇文章中的所有答案:How do I authorise an app (web or installed) without user intervention?,但没有一个显示如何使用刷新令牌在 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 request 方法,因为它更干净并且使用更少的代码。谢谢!

【问题讨论】:

标签: python python-3.x google-api python-requests google-api-python-client


【解决方案1】:

在 Python 中,一种方法是使用 requests-oauthlib 来执行后端应用程序流。当您没有将某人重定向到的前端以批准获取令牌时,这很有用。

【讨论】:

  • 不幸的是,当我获得 oauth.fetch_token() 参数时,使用提供的两种方法都会导致此问题:oauthlib.oauth2.rfc6749.errors.UnsupportedGrantTypeError: (unsupported_grant_type) Invalid grant_type: client_credentials
  • 这可能是因为 Google 的 Oauth 不接受 HTTPBasicAuth() 就是这种 client_credentials 数据类型。你知道我可以调用 .fetch_token() 的另一种方式吗?也许通过在 fetch_token() 中使用“body”或“headers”参数?参考:docs.authlib.org/en/latest/client/api.html#authlib.integrations.requests_client.OAuth2Session。
  • 这是一个(有点无用的)相关 SO 帖子:stackoverflow.com/questions/46751901/…
【解决方案2】:

这个网站 (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

【讨论】:

    【解决方案3】:

    由于上述解决方案都不起作用,我最终不得不放弃并使用服务帐户。

    【讨论】:

      猜你喜欢
      • 2012-05-24
      • 2018-09-27
      • 2015-02-25
      • 1970-01-01
      • 2015-01-03
      • 1970-01-01
      • 1970-01-01
      • 2015-08-01
      • 2014-07-09
      相关资源
      最近更新 更多