Chrome 应用程序中 Google Oauth2 的访问代码 - 凭据无效
Access code for Google Oauth2 in Chrome app - invalid credentials
在网络应用程序中,我开发了一个 client-server authentication 可以正常工作的流程:
- 客户端生成访问码
grantOfflineAccess
- 客户端将代码传递给服务器
- 服务器(同
client_id
),检查代码的完整性,然后要求一个access_token
和一个refresh_token
到Google。
- 令牌被保存以供以后在离线模式下重复使用。
现在我想在 Chrome 应用程序中生成访问代码,以便将访问代码传递到(同一)服务器,以请求令牌以供离线后期重用。
使用与 Web 应用程序相同的 client_id
,我请求带有 chrome.identity.launchWebAuthFlow
的代码,带有此 url 参数(为便于阅读而清理):
https://accounts.google.com/o/oauth2/v2/auth?
scope=profile email https://www.googleapis.com/auth/drive
include_granted_scopes=true
state=state_parameter_passthrough_value // I actually left this as it is
redirect_uri=https://<app-id>.chromiumapp.org/chromelogin
response_type=code
access_type=offline
client_id=[same_as_webapp]
这确实有效,我确实获得了访问代码,作为传递给 chrome.identity.launchWebAuthFlow
的回调的一部分 url。
问题是,当我将访问代码发送到我的 Web 服务器时,当它尝试生成令牌时,我收到一个 Invalid Credentials 401
错误。
我是不是漏掉了什么?
我还尝试使用另一个 client_id
,一个通过应用程序 ID 专门绑定到 Chrome 应用程序。在这样做时,我确实检查了 manifest.json
中的密钥是否等于已安装应用程序提供的密钥(如 here 所述)。但是,成功生成访问码后,服务器收到相同的错误消息。
编辑
服务器端,我使用访问代码来生成令牌:
$aCode = $_POST['authcodefromclient'];
$token = $googleClient->authenticate( $aCode );
这里是 OAuth 流程的简要总结。
第一次请求授权时,您将获得一个短暂的访问代码。使用此访问代码请求离线 刷新令牌。保存刷新令牌。每当您的应用程序需要访问受保护的资源时,它都会使用刷新令牌来请求 访问令牌。当您调用 Google API 时,此访问令牌作为 http 授权 header 提供。根据您的描述,您应该使用访问令牌时却使用了访问代码。
可以通过 chrome.identity.launchWebAuthFlow()
,但这需要 Chrome 用户输入他们的登录凭据。签出这个答案:
Get id_token with Chrome Identity API
如果您长时间不需要访问用户的 Google 帐户,您可以通过 chrome.identity.getAuthToken
的 access_token
获得临时访问权限。我喜欢这个,因为 Chrome 用户不必输入他们的凭据(如果他们登录到 Chrome 浏览器或 ChromeBook)。我将 access_token
传递到我的服务器,然后通过调用验证它:https://www.googleapis.com/oauth2/v3/tokeninfo?access_token={0}
在网络应用程序中,我开发了一个 client-server authentication 可以正常工作的流程:
- 客户端生成访问码
grantOfflineAccess
- 客户端将代码传递给服务器
- 服务器(同
client_id
),检查代码的完整性,然后要求一个access_token
和一个refresh_token
到Google。 - 令牌被保存以供以后在离线模式下重复使用。
现在我想在 Chrome 应用程序中生成访问代码,以便将访问代码传递到(同一)服务器,以请求令牌以供离线后期重用。
使用与 Web 应用程序相同的 client_id
,我请求带有 chrome.identity.launchWebAuthFlow
的代码,带有此 url 参数(为便于阅读而清理):
https://accounts.google.com/o/oauth2/v2/auth?
scope=profile email https://www.googleapis.com/auth/drive
include_granted_scopes=true
state=state_parameter_passthrough_value // I actually left this as it is
redirect_uri=https://<app-id>.chromiumapp.org/chromelogin
response_type=code
access_type=offline
client_id=[same_as_webapp]
这确实有效,我确实获得了访问代码,作为传递给 chrome.identity.launchWebAuthFlow
的回调的一部分 url。
问题是,当我将访问代码发送到我的 Web 服务器时,当它尝试生成令牌时,我收到一个 Invalid Credentials 401
错误。
我是不是漏掉了什么?
我还尝试使用另一个 client_id
,一个通过应用程序 ID 专门绑定到 Chrome 应用程序。在这样做时,我确实检查了 manifest.json
中的密钥是否等于已安装应用程序提供的密钥(如 here 所述)。但是,成功生成访问码后,服务器收到相同的错误消息。
编辑
服务器端,我使用访问代码来生成令牌:
$aCode = $_POST['authcodefromclient'];
$token = $googleClient->authenticate( $aCode );
这里是 OAuth 流程的简要总结。
第一次请求授权时,您将获得一个短暂的访问代码。使用此访问代码请求离线 刷新令牌。保存刷新令牌。每当您的应用程序需要访问受保护的资源时,它都会使用刷新令牌来请求 访问令牌。当您调用 Google API 时,此访问令牌作为 http 授权 header 提供。根据您的描述,您应该使用访问令牌时却使用了访问代码。
可以通过 chrome.identity.launchWebAuthFlow()
,但这需要 Chrome 用户输入他们的登录凭据。签出这个答案:
Get id_token with Chrome Identity API
如果您长时间不需要访问用户的 Google 帐户,您可以通过 chrome.identity.getAuthToken
的 access_token
获得临时访问权限。我喜欢这个,因为 Chrome 用户不必输入他们的凭据(如果他们登录到 Chrome 浏览器或 ChromeBook)。我将 access_token
传递到我的服务器,然后通过调用验证它:https://www.googleapis.com/oauth2/v3/tokeninfo?access_token={0}