如何在弹出窗口中通过 OAuth 2.0 向 Google 进行身份验证?

Posted

技术标签:

【中文标题】如何在弹出窗口中通过 OAuth 2.0 向 Google 进行身份验证?【英文标题】:How to authenticate with Google via OAuth 2.0 in a popup? 【发布时间】:2011-12-18 07:45:02 【问题描述】:

很抱歉进行了大修改。我重新开始,因为我没有正确地陈述我的问题。

我正在尝试用 html5 编写客户端应用程序。我不希望它托管在网站上。我什至不确定这是否可能,我对这种类型的应用程序相当陌生。

无论如何,我想访问谷歌服务,这需要像 OAuth 这样的身份验证。因为它是 javascript,所以听起来 OAuth2 是我需要的。

我正在尝试在弹出窗口中打开 google 身份验证(我有这部分),让用户允许访问,然后将流程传回我的应用程序,该应用程序可以查询 Google 服务。问题是 1. 每当我使用 response_type=code 时,它都会要求用户将令牌复制/粘贴到应用程序中,但如果我使用 response_type=token,它需要我重定向回一个有效的 URL,因为它不是托管在网络服务器,没有。

那么如何使用 OAuth,并让用户无缝授予访问权限?

【问题讨论】:

查看这个答案***.com/a/38094113/1153703 【参考方案1】:

您应该为 Google 定义一些重定向 URL,以便在身份验证完成后重定向到。如果您无法在任何网站上托管您的页面,您可以很好地将其托管在本地主机中。

关于从弹出窗口获取访问令牌到主父窗口,您可以在父窗口中设置一个计时器,不断检查弹出窗口的文档位置。一旦文档位置与重定向 URL 匹配,您就可以解析将在 URL 本身中的访问令牌。

我昨天写了一篇关于完全相同问题的教程(使用本地主机),这里是链接: http://www.gethugames.in/2012/04/authentication-and-authorization-for-google-apis-in-javascript-popup-window-tutorial.html

希望你会发现它有用。

【讨论】:

我阅读了你的教程,我想知道是否可以按照你建议的方式获取令牌,一旦令牌存储在父窗口中,使用 php 进行 API 调用。我想要这种方式的原因是我正在使用 google-api-php-client 库。谢谢你 我相信 google-api-php 库中会有功能来授权和获取访问令牌。为什么你不能使用它们? code.google.com/p/google-api-php-client/wiki/OAuth2 因为我在尝试实现一系列的表单,或者一个流程。如果访问令牌或刷新令牌不可用,则用户需要在流程的每个阶段授权访问日历和电子表格、b/c,或在提交表单(多部分表单流程)后记录已流逝的时间并在日历和电子表格中形成数据。使用 php 库的问题是它会打开同一个页面,我无法从第一个启动过程表单返回 POST。 您可以编写一个 php 文件(可以将其命名为 settoken.php),它将令牌字符串作为 POST 参数,将其保存为 PHP 会话变量并恢复您暂停以获得用户身份验证的过程。然后在客户端,在用户身份验证结束并且您获得令牌并对其进行验证后,您可以将其发布到 settoken.php。但是令牌需要以某种方式传递给服务器,我认为您不能访问存储在窗口中的令牌来调用您的 php 库。 真的很不错。您的样本似乎比 google +10 提供的样本更好【参考方案2】:

为避免潜在的click jacking,Google 身份验证会强制您进行全页登录。我认为你无法控制它。

编辑评论后,这是从Google OAuth2 page中提取的代码:

<body>
    <a href="javascript:poptastic('https://accounts.google.com/o/oauth2/auth?scope=https://www.google.com/m8/feeds&client_id=21302922996.apps.googleusercontent.com&redirect_uri=https://www.example.com/back&response_type=token');">Try
    out that example URL now</a>
<script>
    function poptastic(url) 
      var newWindow = window.open(url, 'name', 'height=600,width=450');
      if (window.focus) 
        newWindow.focus();
      
    

</script>
</body>

【讨论】:

我不确定这是不是真的。在他们自己的示例网页code.google.com/apis/accounts/docs/OAuth2.html#ClientLibraries 上,有一个链接显示“立即试用示例 URL”,如果单击该链接,则会在新的弹出窗口中打开它。 我已经更新了答案。我试图将它嵌入到 iframe 中,这可能是重定向页面的原因。感谢您提供信息。 对不起,我已经能拿到那部分了。窗口打开,但它希望您将一些身份验证令牌复制/粘贴到我不想要的客户端应用程序中。我希望用户单击“允许”,然后继续。这是我想不通的部分。 您是否尝试将redirect_uri 指定到您网站的页面。然后读取令牌#access_token,将其传递给父页面,关闭弹出窗口,并在后续调用中使用它? 你不是纯粹在客户端运行它,因为你调用了谷歌。【参考方案3】:

我相信您可以在 Javascript 中使用 google api (gapi) 进行 Oauth。 这是文档:Authentication using the Google APIs Client Library for JavaScript

您不需要用户复制/粘贴任何代码,也不需要提供重定向 uri

您需要做的就是:转到Google Developers Console 中的项目并生成以下内容: 1. 生成新的客户端 ID 并选择选项“已安装的应用程序”和“其他”。 2. 生成公共 API 密钥

来自上述文档的示例代码:

// Set the required information
var clientId = 'YOUR CLIENT ID';
var apiKey = 'YOUR API KEY';
var scopes = 'https://www.googleapis.com/auth/plus.me';

// call the checkAuth method to begin authorization
function handleClientLoad() 
  gapi.client.setApiKey(apiKey); // api key goes here
  window.setTimeout(checkAuth,1);


// checkAuth calls the gapi authorize method with required parameters
function checkAuth() 
  gapi.auth.authorize(client_id: clientId, scope: scopes, immediate: true, handleAuthResult); // scope and client id go here


// check that there is no error and makeApi call
function handleAuthResult(authResult) 
  var authorizeButton = document.getElementById('authorize-button');
  if (authResult && !authResult.error) 
    makeApiCall();
  


// API call can be made like this:
function makeApiCall() 
  gapi.client.load('plus', 'v1', function() 
    var request = gapi.client.plus.people.get(
      'userId': 'me'
    );
    request.execute(function(resp) 
      var heading = document.createElement('h4');
      var image = document.createElement('img');
      image.src = resp.image.url;
      heading.appendChild(image);
      heading.appendChild(document.createTextNode(resp.displayName));

      document.getElementById('content').appendChild(heading);
    );
  );

【讨论】:

【参考方案4】:

我已经为这个任务写了一个迷你 JS 库,拿来看看它是否适合你。

https://github.com/timdream/wordcloud/blob/6d483cd91378e35b54e54efbc6f46ad2dd634113/go2.js

我最近正在开发另一个依赖相同脚本的项目,所以我将这个项目隔离到 an independent library project ... 检查进度如下(如果有的话)。

【讨论】:

顺便说一下,timc.idv.tw/wordcloud 完全符合 Google 身份验证方式的客户端网络应用程序。

以上是关于如何在弹出窗口中通过 OAuth 2.0 向 Google 进行身份验证?的主要内容,如果未能解决你的问题,请参考以下文章

通过弹出窗口进行 Twitter OAuth

如何在添加窗口中通过 html 助手更改弹出剑道网格的标题

在弹出窗口中从 iframe 向后台脚本发送消息

如何重置 google oauth 2.0 授权?

OAuth 2.0 与 OpenID Connect 协议的完整指南

当用户在弹出窗口之外点击时,防止 JQuery Mobile 关闭弹出窗口