Google OAuth2 - 令牌的交换访问代码 - 不起作用

Posted

技术标签:

【中文标题】Google OAuth2 - 令牌的交换访问代码 - 不起作用【英文标题】:Google OAuth2 - Exchange Access Code For Token - not working 【发布时间】:2014-02-04 01:08:53 【问题描述】:

我目前正在实施服务器端 OAuth2 流程以授权我的应用程序。

JS 应用程序将代表注册的 CMS 帐户向最终用户(拥有与 CMS 帐户合作的频道)显示 YouTube 分析数据。因此,授权阶段需要对用户完全隐藏。我正在尝试授权一次,然后在需要时使用“永久”授权代码来检索访问令牌。

我能够成功授权并检索访问代码。当我尝试将访问代码交换为令牌时,问题就开始了。

实现此目的的 HTTP POST 请求需要如下所示...

POST /o/oauth2/token HTTP/1.1
Host: accounts.google.com
Content-Type: application/x-www-form-urlencoded

code=4/P7q7W91a-oMsCeLvIaQm6bTrgtp7&
client_id=8819981768.apps.googleusercontent.com&
client_secret=client_secret&
redirect_uri=https://oauth2-login-demo.appspot.com/code&
grant_type=authorization_code

我正在使用此代码来实现此目的:

var myPOSTRequest = new XMLHttpRequest();



myPOSTRequest.open('POST', 'https://accounts.google.com/o/oauth2/token', true);
myPOSTRequest.setRequestHeader('content-type', 'application/x-www-form-urlencoded');
myPOSTRequest.send('code=' + myAuthCode + '&redirect_uri=http%3A%2F%2Flocalhost%2FCMSAuth3.html&client_id=626544306690-kn5m3vu0dcgb17au6m6pmr4giluf1cle.apps.googleusercontent.com&scope=&client_secret=my_client_secret&grant_type=authorization_code');

我可以成功获得对此请求的 200 OK 响应,但是没有返回访问令牌,并且 myPOSTRequest.responseText 返回一个空字符串。

我玩过 Google 的 OAuth Playground - 并且可以使用我自己的凭据成功获取令牌。

我错过了什么吗?

【问题讨论】:

在您的代码中,您使用“授权码”作为您的授权类型。 嗨,Emily,我很抱歉我粘贴了错误的示例 - 使用 grant_type=authorization_code 编辑了准确的示例 粘贴实际的 http 请求和响应。将这些与 Oauth Playground 的等价物进行比较 @pinoyyid OAuth 游乐场似乎通过在服务器端执行实际请求来掩盖实际请求 @Michael 请求和响应显示在网页上 【参考方案1】:

你不能这样做,因为有same origin policy。这是现代浏览器的一个安全概念,它可以防止 javascript 从您的站点之外的其他来源获取响应。这是一个重要的概念,因为它使您能够保护您免受CSRF 的侵害。所以不要使用代码授权流程,而是使用token authorization flow。

【讨论】:

我最终意识到了这一点,所以我现在有一个 php 文件来检索该访问令牌,并将其保存到 .txt 文件中以供客户端应用程序使用。我现在的问题是尝试加载 API,因为我有这个访问令牌。我尝试过使用 XMLHttpRequest(),但遇到了相同的跨域问题(尽管谷歌文档说明这是 CORS 友好的方式) 好吧,我不确定,因为我没有尝试,但也许谷歌区分了访问令牌,通过授权流和令牌流检索。尝试使用 Fiddler 并查找,如果 Google 发送类似 Access-Control-Allow-Origin: * 的标头【参考方案2】:

尝试构建完整的 URL。然后将其转储到网络浏览器中。如果它正确,您将获得 json。你有正确的格式。

https://accounts.google.com/o/oauth2/token?code=<myAuthCode>&redirect_uri=<FromGoogleAPIS>&client_id=<clientID>&client_secret=my_client_secret&grant_type=authorization_code

其他需要检查的事项:

    确保您使用的是在 google api 中设置的相同 redirect_uri。 如何取回 Authcode?如果您从页面标题中提取它,我遇到的问题是它没有在标题中返回完整的授权码,请尝试检查页面的正文。这不会一直发生。我只是偶尔。

【讨论】:

我总是遇到这个异常。任何线索为什么? error: "invalid_request" error_description: "必需参数丢失:grant_type" 这是 GET 还是 POST 请求? @PuneetPandey 这是一个POST请求,你有没有试过服务器side implementation。它对我有用

以上是关于Google OAuth2 - 令牌的交换访问代码 - 不起作用的主要内容,如果未能解决你的问题,请参考以下文章

从 Firebase 云函数调用时,OAuth2 访问令牌交换失败

无法在跨客户端谷歌 oauth2.0 中交换访问令牌和刷新令牌的授权码

即使访问令牌有效,也无法使用刷新令牌刷新 Google OAuth2 的访问令牌

Spring 5,401 返回后带有 Google 刷新访问令牌的 OAuth2

了解 Google OAuth2 刷新令牌

如何存储访问令牌? (Oauth 2,Auth 代码流程)