【发布时间】:2021-02-28 01:12:27
【问题描述】:
我正在寻找一些关于如何在 Python 中设计和创建我自己的桌面应用程序(或 installed app)的最佳实践示例代码,需要向 Google 提供 OAuth 2.0 授权流程,并找到了 Google 提供的这个存储库:https://github.com/googlesamples/oauth-apps-for-windows(用 C# 编码,但无论如何设计应该是相同的)。
在深入研究代码时,我惊讶地发现client_secret 直接清晰地嵌入到源代码中(看这里:https://github.com/googlesamples/oauth-apps-for-windows/blob/e79f1575b5858c5f617d29f2435a93996e4248c5/OAuthConsoleApp/OAuthConsoleApp/Program.cs#L47)。
我在Google Developers documentation about "Installed applications" 上找到了这个:
当您通过 Google API 控制台创建客户端 ID 时,指定这是一个已安装的应用程序,然后选择 Android、Chrome、iOS 或“其他”作为应用程序类型。该过程会生成一个客户端 ID,在某些情况下,还会生成一个客户端密码,您可以将其嵌入到应用程序的源代码中。 (在这种情况下,客户端机密显然不被视为机密。)
另外,我不知道为什么 Android 或 iOS 应用程序不会在控制台生成的 OAuth 客户端 ID 中包含这个 client_secret,而其他本机应用程序(桌面)应该包含。
而且我还在许多网站上发现,客户端机密应该保密……正如其名称所暗示的那样。
我已经阅读了本地应用程序的不同 RFC(我相信最可靠的来源)并发现这很有用:
https://datatracker.ietf.org/doc/html/draft-ietf-oauth-native-apps-12#appendix-A:
- 不假定本机应用程序客户端可以保密。如果机密被分发到同一本机应用程序的多次安装,则不应将其视为机密。请参阅第 8.5 节。
但我想确保我理解正确。
那么,在从 Google API 控制台为“其他”应用程序类型生成 OAuth 客户端 ID 后,是否可以将客户端密码直接嵌入到我的应用程序中?这样做真的没有安全问题吗?这个 SO 帖子:What the attacker could do if he obtains application's client_secret? 谈论安全问题,所以我有点迷茫。
使用google-auth-oauthlib避免从头实现OAuth协议,我可以安全地分发以下代码吗(****的值显然不会被混淆):
from google_auth_oauthlib import flow
# generated from Google API Console ("other" application)
client_config = {
"installed": {
"client_id": "****.apps.googleusercontent.com",
"client_secret": "****", # is it safe?
"project_id": "****",
"auth_uri": "https://accounts.google.com/o/oauth2/auth",
"token_uri": "https://oauth2.googleapis.com/token",
"auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs",
"redirect_uris": [
"urn:ietf:wg:oauth:2.0:oob"
]
}
}
scopes = ['https://www.googleapis.com/auth/books'] # example
appflow = flow.InstalledAppFlow.from_client_config(client_config, scopes=scopes)
appflow.run_console()
credentials = appflow.credentials
# some code requesting Google APIs for the required scopes
如果恶意用户发现了client_secret,他可以用这个做什么?
【问题讨论】:
-
我也有同样的问题。以下两个答案似乎表明
client_secret对于本机应用程序不需要保密:stackoverflow.com/q/20558863/3040129 和 stackoverflow.com/q/44312000/3040129 -
@illabout 感谢您提供有用的链接。我仍然不明白 Android/iOS(不包括
client_secret)和桌面应用程序(需要嵌入client_secret)之间的区别。就像您在其中一个帖子中所说的那样,它看起来像是一个“奇怪”。另外,我主要关心的是安全性,我不知道恶意用户可以用client_secret做什么,即使这种情况下它不被视为真正的“秘密”。我找不到任何可靠的来源(预计是 RFC)谈论这个。 -
@norbjd 您最终为此采用了什么解决方案?我一直在绕圈子试图回答这个问题,但我觉得我永远学不到足够的知识来解决这个问题。
-
@AaronCiuffo 在我们的例子中,我们决定在源代码中添加 client_secret,就像在 Google 示例中一样。但是这个应用程序的用户是我们公司的用户,所以使用 client_secret 做坏事的风险被降低了,因为只有少数已知用户使用我们的应用程序。
-
@norbjd 我猜对用户级谷歌应用程序的需求不足,因此没有更好的解决方案。这有点令人沮丧,但除非我想让我的应用基于网络,否则我将不得不忍受它。
标签: python-3.x security oauth-2.0 google-oauth