繁体   English   中英

节点 Google OAuth2 redirect_uri_mismatch

[英]Node Google OAuth2 redirect_uri_mismatch

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

任何的想法?

谷歌重定向不匹配

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

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

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

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

您需要将 auth url 传递到前端,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部分中绑定的事件发射器侦听器,它将把我们的数据返回给应用程序,最后我们将一个简单的html 页面发送到带有javascript one liner 的弹出窗口,上面写着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();
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM