【问题标题】:Google calendar and client secrets with desktop app带有桌面应用程序的 Google 日历和客户端机密
【发布时间】:2014-11-09 05:50:55
【问题描述】:

我正在尝试弄清楚 oauth 流程将如何适用于我的 google 日历应用程序。我有一个桌面应用程序,我将分发它并将使用谷歌日历。我知道有一个客户端机密,但我想知道是否有办法请求令牌而不是一起发送客户端机密文件。我担心有人只会在日历上发送垃圾邮件,而我的应用程序对其他人不起作用。这是一种可能吗?有哪些解决方案可以缓解这种情况?

谢谢,

【问题讨论】:

    标签: python oauth-2.0 google-calendar-api


    【解决方案1】:

    使用 OAuth2,客户端密码用于向 Google 验证您的应用,反之亦然。 OAuth2 服务器只会向提交正确客户端 ID 和客户端密码(以及其他内容)的应用程序颁发令牌。这种安排(部分)正是为了确保其他人不能(例如)“向您的日历发送垃圾邮件”。否则,Google 怎么知道发出请求的应用程序实际上是合法的,而不是垃圾邮件发送者制作的恶意代码以看起来像您的应用程序?

    在您可以使用 OAuth2 之前,您的应用程序已在 Google 注册。作为此过程的一部分,Google 会向您发送一个客户端密码,然后您必须将其构建到您的应用程序实例中。此应用程序实例还与授权握手完成时的重定向 URI 相关联。

    这样做的结果是,如果每次部署都必须经过注册过程,您就无法真正分发使用 OAuth2 的应用程序。如果您尝试将机密与您的应用程序一起分发,那么它就不再是机密,而且无论如何,您无法知道可能部署它的所有 URI。

    我对我正在开发的应用程序采取的一种方法是让应用程序读取一个客户端机密文件,该文件必须由应用程序的安装程序根据他们自己的注册提供。它的格式基于您注册应用程序时 Google 提供的 JSON 下载。要求每个安装人员都经历这个过程是一件很痛苦的事情,但就目前的情况而言,我认为没有更简单的方法也是安全的。

    例如,我有一个使用 Google 的 OpenID Connect 身份验证实现,它基于 oauth2client 库,并使用基于 Google 客户端机密文件的文件格式。当一项服务向 Google 注册以使用 OAuth2 时,Google 可以提供一个“客户端机密”文件,如下所示:

    {
      "web": {
        "client_id": "9876543210.apps.googleusercontent.com",
        "client_secret": "secret-12345678901234567890",
        "client_email": "9876543210@developer.gserviceaccount.com",
        "client_x509_cert_url": 
            "https://www.googleapis.com/robot/v1/metadata/x509/9876543210@developer.gserviceaccount.com",
        "redirect_uris": 
          [ "http://localhost:8000/annalist/login_done/", 
            "http://annalist-demo.example.org:8000/annalist/login_done/"
          ],
        "auth_uri": "https://accounts.google.com/o/oauth2/auth",
        "token_uri": "https://accounts.google.com/o/oauth2/token",
        "auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs"
      }
    }
    

    在我的代码中,我使用此文件通过 oauth2client 库启动 OAuth2 流,代码如下所示:

    flow = flow_from_clientsecrets(
        clientsecrets_filename,
        scope=scope,
        redirect_uri=request.build_absolute_uri(login_done)
        )
    

    因此您可以看到,除了启动流程时使用的客户端 ID 之外,还有更多信息。我的实现的完整代码位于https://github.com/gklyne/annalist/blob/master/src/annalist_root/oauth2/views.py,大约从第 273 行开始,但该模块中有更多逻辑与将详细​​信息传递回在 Django 框架中运行的应用程序有关。

    我还创建了documentation 用于向 Google 注册应用程序并部署客户端凭据的过程。请注意,这些说明是针对身份服务而不是日历 API 的,并且详细信息是针对我的应用程序的,但我希望有足够的通用性来帮助您。


    展望未来,IETF 正在制定一个规范,以允许自动注册使用 OAuth2 的应用程序实例。我认为这是相关规范:https://datatracker.ietf.org/doc/draft-ietf-oauth-dyn-reg/。目前(截至 2014 年 9 月)似乎正在考虑将其发布到标准跟踪出版物中,但这并没有说明何时可以更广泛地使用它。

    【讨论】:

    • 非常感谢您提供的信息,非常感谢。然而,我有点困惑这是如何工作的。所以到目前为止我有两个字段:客户端密码和客户端 ID。我知道 ID 是客户的标识,但我认为秘密是 soarts 的密码。基本上,这是阻止人们假装是我的应用程序并用请求淹没谷歌的原因。根据您的说法,客户端密码是按客户端生成的。效果如何?很抱歉造成混乱,非常感谢您的帮助。
    • 是的,客户端 ID 标识客户端,但客户端密码验证客户端。你一起使用它们。我在github.com/gklyne/annalist/blob/master/src/annalist_root/oauth2/… 有一个适用于Django 的OAuth2 模块,它建立在@bitworker 的oauth2client 库之上。关键步骤大约是第 318 行,它接受一个“客户端机密”文件,其中包含客户端 ID、客户端机密等”。
    • 我在答案中添加了一些示例代码,以尝试充实我上面所说的内容。
    猜你喜欢
    • 1970-01-01
    • 2021-07-19
    • 2014-01-10
    • 1970-01-01
    • 1970-01-01
    • 2017-10-24
    • 2019-12-19
    • 2020-07-17
    • 2022-01-24
    相关资源
    最近更新 更多