节点Google OAuth2 redirect_uri_mismatch

时间:2014-05-13 18:07:16

标签: node.js oauth-2.0 google-oauth

附件是我的google凭据窗口的屏幕截图,其中包含我的重定向URI,右边是由Nodejs Google OAuth2客户端注册的redirectURI,它在请求中发送但我的响应仍然返回 redirect_uri_mismatch

有什么想法吗?

google redirect mismatch

2 个答案:

答案 0 :(得分:3)

只是为uri不匹配错误添加另一个原因。如果您在客户端生成令牌并尝试在服务器端调用getToken,则REDIRECT_URI必须在客户端域中添加,并添加到控制台API中。

答案 1 :(得分:1)

原因是问题出现了,因为我试图通过前端google plus js api交换提供给我的非离线 access_type 。我无法找到一种方法从谷歌通过弹出窗口检索完整的离线访问代码,以便发送到我的服务器以换取长期生活令牌。

我构建了自己的弹出重定向流程。我没有找到任何资源以正确的方式使用弹出窗口执行完整身份验证而不重定向主页面,所以我即兴创作。我愿意接受改进,但这对我有用,无论如何,如果有人想这样做也是我的工作流程。

如何设置自己的弹出式oauth身份验证流程

您需要将auth网址传递到nodejs googleapis库轻松使用的前端:

url = this.oauth2Client.generateAuthUrl(access_type: 'offline', scope: myScope)

以某种方式将其传递给前端,接下来当用户启动网站上的oauth按钮时,它会打开弹出窗口(请求1),同时发送等待最终结果的请求(请求2)

// Front end Angular function to initiate the popup
signup: function(callback) {
  this.$window.open(googleOauthURL, 'Authenticate Google', 'width=600, height=600');
  return this.$http.get('auth/google/awaiting').success(function(res) {
    return callback(res);
  });
}

在后端,这里是响应请求2 的coffeescript代码。我添加了150秒的超时时间,其中说:如果我们在150秒内未通过其身份验证凭据获得用户的响应,则关闭连接。 (我们不想挂连接)

exports.awaiting = (req, res) ->
    # Build a unique listener for the correct ip address
    listener = 'oauthAwait-' + req.ip

    # Clear any possible pre-existing listener
    google.removeAllListeners(listener)

    timeoutProtect = setTimeout ->
        google.removeAllListeners(listener)
        timeoutProtect = null

        res.json
            success: false
            error: 'Timedout'
            data: null
    , timeoutLength

    google.once listener, (result) ->
        if timeoutProtect
            clearTimeout(timeoutProtect)

            res.json(result)# return the data

接下来,我们等待用户验证弹出窗口。当他们这样做时,它将重定向到我们在开发控制台中指定的重定向uri 。我们的服务器将获取代码,请求谷歌长期生活 access_token ,我们有我们需要的。

exports.oauthCallback = (req, res) ->
    listener = 'oauthAwait-' + req.ip

    successCallback = (user) ->
        user.success = true
        # trigger the request 2 listener with the data
        google.emit(listener, user)

    failCallback = (err) ->
        error.success = false
        google.emit(listener, error)

    exchangeToken(req, req.query.sessionState)
        .then(doSomethingWithToken, failCallback)
        .then(successCallback, failCallback)
        .fin ->
            # return a page that closes itself to the popup (request 1)
            res.render 'oauthPopupCallback'

在这里,我们交换令牌然后用它做一些事情。一旦我们得到用户,我们就会触发我们在 exports.awaiting 部分中绑定的事件发射器侦听器,该部分将我们的数据返回给应用程序,最后我们使用javascript向弹出窗口发送一个简单的html页面一个说window.close()

的班轮

然后我们在后端有一个完全认证的用户access_token。如果用户支持,可以通过使用Web套接字来改进,以替换挂起请求。

修改
在那里发现了一个名为window.opener的弹出窗口上的这个花花公子方法,可以访问打开弹出窗口的窗口。实质上,这取代了挂起并等待弹出窗口响应的请求2的需要。

在弹出窗口中,您可以使用javascript将数据传递到主窗口,如:

var service = ResponseData,
    callback = 'on' + service.name + 'Auth';

window.onload = function () {
    window.opener[callback](service.data);
    window.close();
}