谷歌OAuth总是显示同意屏幕 我正在构建一个安装的应用程序,它将需要使用Qt和C++的谷歌RealtREST API的特性。我知道Qt现在发布了新的库来支持OAuth流,但假设我是一名学生,学习在这一层使用OAuth是这个项目的一项要求

谷歌OAuth总是显示同意屏幕 我正在构建一个安装的应用程序,它将需要使用Qt和C++的谷歌RealtREST API的特性。我知道Qt现在发布了新的库来支持OAuth流,但假设我是一名学生,学习在这一层使用OAuth是这个项目的一项要求,c++,qt,openid-connect,google-oauth,google-openid,C++,Qt,Openid Connect,Google Oauth,Google Openid,在我的应用程序中,我有一个用于已安装应用程序的工作OAuth流,该流以使用QSettings存储的访问令牌和刷新令牌结束(我也愿意输入这是否是一个灾难性的坏主意)。该应用程序本身不需要身份验证/登录/数据,但它确实需要通过谷歌身份验证来使用访问令牌调用API。此应用程序没有被托管的关联web后端;它很简单,应该可以完全在本地部署(我已经编写并包含了一个简单的TCP服务器,它将接收授权重定向uri,并在从应用程序中调用时运行和关闭) 因此,我对确保当用户打开我的应用程序并希望使用Google Dr

在我的应用程序中,我有一个用于已安装应用程序的工作OAuth流,该流以使用QSettings存储的访问令牌和刷新令牌结束(我也愿意输入这是否是一个灾难性的坏主意)。该应用程序本身不需要身份验证/登录/数据,但它确实需要通过谷歌身份验证来使用访问令牌调用API。此应用程序没有被托管的关联web后端;它很简单,应该可以完全在本地部署(我已经编写并包含了一个简单的TCP服务器,它将接收授权重定向uri,并在从应用程序中调用时运行和关闭)

因此,我对确保当用户打开我的应用程序并希望使用Google Drive功能时,他们在Google端得到适当身份验证的最佳方法感到好奇。比方说,如果我在注册表中维护一个访问令牌,并且该访问令牌是根据每个用户/每个应用程序授予的(对吗?),那么我如何确保只有该令牌所属的用户能够使用它调用API

以下是我的理解和方法;如果我有错误的解释,请随时纠正我或教育我

如果找到访问令牌,请执行以下操作:
  • 打开指向Google登录域的浏览器页面,并让用户在其中进行身份验证(这可能会禁止用户使用缓存的登录会话,该会话可以访问他们本不应该访问的令牌)
  • 如果用户使用Google帐户正确地进行了身份验证,则将控制权返回应用程序,并使用存储的令牌对API进行测试调用
  • 如果调用失败(响应为
    无效的\u凭证
    ),我应该能够确定它的有效性,因为访问令牌已过期,应用程序将通过流从刷新令牌续订访问令牌
  • 如果最初未找到访问令牌:
  • 启动普通OAuth安装的应用程序流
  • 获取令牌并存储它们,以便用户下次打开应用程序时使用前一个过程
  • 如果找到访问令牌,那么我的问题是前两个步骤。名义上,这可以由典型的OAuth流来完成,但是当使用localhost作为重定向uri时,Google似乎总是会提示同意,而不管
    提示符
    访问类型
    授权查询参数的设置如何

    如何以我的应用程序可以控制的方式完成前两个步骤(即不是一个依赖于某个地方托管的后端服务器的解决方案)

    如果这个问题对于SO需求来说过于开放,我可以做更多的限制/假设来限制问题领域,但我还是不想这样做,以防我在不知不觉中找到一个好的可行的解决方案


    谢谢你的阅读!抱歉,如果这是一个冗长;我想确保我的问题领域得到充分充实

    如果您使用的是已安装的应用程序,我不建议使用或存储刷新令牌。在客户端存储刷新令牌意味着,如果入侵者获得了对客户端应用程序的访问权,他们就可以无限地访问用户的应用程序,而无需输入用户的凭据。如果您坚持要使用刷新令牌,请确保遵循Google的,并在您的请求中包含
    code\u验证程序
    参数

    如果找到访问令牌,您应该,如果已验证,然后在google api上使用它,否则将强制用户再次登录(如果您选择仍然使用刷新令牌,则刷新它)

    如果找不到访问令牌,您的流听起来很正常

    关于登录谷歌的一些注意事项:

  • 如果您在身份验证请求中指定
    access\u type=offline
    ,Google将只返回刷新令牌
  • 除非您总是在查询参数中指定
    prompt=approve
    ,否则Google只会在用户的第一次授权请求中返回刷新令牌
  • 根据我的经验,当省略
    提示
    查询参数时,不会再次提示用户同意。如果他们登录到谷歌,你将获得一个新的访问令牌,但没有刷新令牌,除非你有
    prompt=approve
  • 我认为,如果您没有用户使用您的应用程序的记录,那么您可以使用
    prompt=approve
    。否则,如果他们以前使用过,您只需
    prompt=none

  • 这只是我对它的理解。

    我最终使用的方法只是部署一个SQLite db,它将存储在AppData roaming目录中。db模式包括一个用户名字段(如果存在,来自OpenID IDToken字段)、用户图片URL(如果存在,同样来自IDToken)、刷新和访问令牌字符串(当我开始使用时将存储为加密字符串)、用户UID/子字符串以及用户名和密码字段

    后两个字段是我自己的应用程序中的身份验证字段,我想再次避免,但似乎不可能这样做。因此,将提示用户在表单中输入用户名和密码,并根据前面提到的现有SQLite db文件检查这些凭据

    • 如果它们存在且正确,则用户将登录并有权访问各自的访问和刷新令牌
    • 如果用户忘记了密码,他们将被要求重新发送(再次通过已安装的应用程序流),以及他们在初始阶段提供的任何密码