无法获取 Google Analytics API 的 oAuth2 访问令牌

Posted

技术标签:

【中文标题】无法获取 Google Analytics API 的 oAuth2 访问令牌【英文标题】:Cannot get oAuth2 Access Token for Google Analytics API 【发布时间】:2013-03-25 18:45:35 【问题描述】:

我正在使用 Rails + Garb Gem (Sija Branch) + omniauth-google-oauth2 Gem,我可以通过 Google Analytics API 成功进行身份验证并提取我们的应用在使用用户登录时生成的数据,例如:

Garb::Session.login('USERNAME', '<PASSWORD>')

然后我可以使用 Garb 连接到我想要的分析配置文件并从中提取数据并在网页上显示一些图表。这一切都很好。

但是,我想使用 oAuth2 通过 Analytics 进行身份验证,这就是为什么我必须从 Github 安装 Garb Gem 的 Sija 分支(它支持 oAuth2),并且我还安装了 omniauth-google-oauth2 Gem。现在理论上我应该能够使用以下代码进行身份验证:

Garb::Session.access_token = access_token # an instance of OAuth2::Client

在这一点上,它对我来说有点朦胧,我非常感谢一些指导。以下是我已经走了多远:

1) 我在 Google API 控制台中创建了一个 Project,并在 Services 下打开了 Analytics API

2) 这为我提供了客户端 ID 和客户端密码

3) 我遇到了这段代码,我可以用上面的 ID 和 Secret 填充它:

client = OAuth2::Client.new(
GOOGLE_CLIENT_ID,
GOOGLE_CLIENT_SECRET,

    :site          => 'https://accounts.google.com',
    :authorize_url => '/o/oauth2/auth',
    :token_url     => '/o/oauth2/token'
)

4) 然后是下一段代码:

response = OAuth2::AccessToken.new(
    client,
    STORED_TOKEN, 
    refresh_token: STORED_REFRESH_TOKEN,
    expires_at: STORED_EXPIRES_AT
)

5) 然后在理论上连接:

Garb::Session.access_token = response

我的问题是我没有上面第 (4) 点中的令牌信息。在我看来,使用 oAuth2 我需要进行一次“握手”并打印出返回令牌值?也许通过 Rails 代码打印返回的值,然后将标记值粘贴到 Rails 应用程序中的常量中,以便我可以在上面的代码中使用它们?我真的很困惑。正如我之前提到的,Web 应用程序使用用户登录身份验证可以正常工作。 Web 应用程序所做的只是通过分析进行身份验证、提取一些数据并绘制图表。但是我坚持将其转换为 oAuth2,因为 我只是不知道如何获取 Garb Gem 正在寻找的访问令牌。我还应该注意,这是不是一个有多个用户进行身份验证的公共网站,这是一个连接到我们自己的分析数据的 CMS 网站。

我已经看到了这方面的一些部分 sn-ps,但不是一个完全解释或工作的例子。对于这个问题,我非常感谢任何指导和帮助。

非常感谢,

JR

【问题讨论】:

【参考方案1】:

在过去的几周里,我一直在努力解决这个问题,所以让我分享一下有效的方法:

要使用 Oauth2,您需要获得一个“刷新令牌”,每次调用 API 时,您都可以使用该令牌向 Google 进行“重新验证”。具体步骤如下:

1) 在 API 控制台中设置您的帐户 - https://code.google.com/apis/console/b/0/(看起来您做得很好) 2) 在您的 API 帐户中,确保您有一个重定向 URI 指向您的应用程序:

http://some-url.com/auth/google_oauth2/callback
http://localhost:3000/auth/google_oauth2/callback

请注意,google 不会让您以 0.0.0.0:3000 的形式回叫本地计算机...因此您需要明确使用 localhost

3) 在您的路由文件中,将该重定向 url 绑定到您将要创建项目或身份验证的控制器中的操作

match '/auth/:provider/callback' => 'authentications#create'

“:provider”只是让您匹配多种类型的 oauth,但您也可以将“google_oauth2”放在那里。

4) 现在在您的控制器中创建该操作

def create
  auth = request.env["omniauth.auth"] 
  params = request.env["omniauth.params"]
  project = Project.find(params['project_id'])

  Authentication.create(:project_id => project.id, :provider => auth['provider'], :uid => auth['uid'], :access_token => auth['credentials']['refresh_token'])
  flash[:notice] = "Authentication successful."
  redirect_to owner_view_project_path(project)
end

5) 控制器操作应该从响应对象中检索相关字段(此处响应对象的详细信息:https://github.com/zquestz/omniauth-google-oauth2) - 特别是,您需要获取“刷新令牌”并将其保存到您的项目或身份验证对象中 -如果您尚未向所需对象添加“access_token”属性,请立即迁移,然后开始将刷新令牌保存到该属性

6) 现在,当您准备好调用该特定身份验证并为其获取 API 数据时,您可以加载保存访问令牌的对象,并使用该对象获取与 google API 的新会话,如下所示:

  @authentication = Authentications.find(params[:id])

  client = OAuth2::Client.new GOOGLE_CLIENT_ID, GOOGLE_CLIENT_SECRET,
                                  
                                    :site => 'https://accounts.google.com',
                                    :authorize_url => "/o/oauth2/auth",
                                    :token_url => "/o/oauth2/token",
                                  
  response = OAuth2::AccessToken.from_hash(client, :refresh_token => @authentication.access_token).refresh!
  Garb::Session.access_token = response
  @profiles = Garb::Management::Profile.all

此代码所做的是通过指定客户端和 refresh_token 创建 OAuth2 访问令牌(响应),然后调用“刷新!”获取刷新的访问令牌...然后使用该访问令牌建立您的 Garb 会话,然后使用 Gard::Management::Profile.all 调用给定帐户的所有配置文件

希望这会有所帮助 - 如果您有任何问题,请告诉我!

【讨论】:

非常感谢您的详细回答。实际上,我使用相同的 Rails 让它工作,但使用 cURL 来获取访问/刷新令牌。直到现在我才被允许回答我自己的问题,所以我将把它放在下面的答案中,并将你的问题标记为正确。再次干杯! 我做了同样的事情,我得到了这个错误 *** OAuth2::Error Exception: GDatainsufficientPermissionsInsufficient Permission【参考方案2】:

请说明对我有用的内容:

对于步骤 3、4 和 5,我使用 cURL 来检索访问/刷新令牌。第 6 步对我来说也是一样的(使用 Garb Gem 的 Sija 分支)。所以使用 cURL:

使用与您的 Google 应用相关的详细信息使用 cURL 发布以下内容:

curl --data "code=<APP_CODE>&redirect_uri=http://localhost:3000/oauth2callback&client_id=<CLIENT_ID>.apps.googleusercontent.com&scope=&client_secret=<CLIENT_SECRET>&grant_type=authorization_code" https://accounts.google.com/o/oauth2/token

响应采用以下形式:


  "access_token" : "<ACCESS_TOKEN>",
  "token_type" : "Bearer",
  "expires_in" : 3600,
  "refresh_token" : "<REFRESH_TOKEN>"

您可以按照第 6 部分将其插入 Garb Gem。

【讨论】:

【参考方案3】:

@CamNorgate 的回答是有效的。

如果您在回调中没有从 Omniauth 返回的“refresh_token”,请确保您正确初始化 :google_oauth2

Rails.application.config.middleware.use OmniAuth::Builder do
  provider :google_oauth2, ENV["GOOGLE_CLIENT_ID"], ENV["GOOGLE_CLIENT_SECRET"],
     :scope=>"https://www.google.com/m8/feeds, https://www.googleapis.com/auth/userinfo.email, https://www.googleapis.com/auth/userinfo.profile",
      :approval_prompt=>"force", access_type="offline"
    

end

确保包含 :approval_prompt=>"force", access_type="offline" 以便将 refresh_token 发回。 The refresh_token is only provided on the first authorization from the user.

【讨论】:

以上是关于无法获取 Google Analytics API 的 oAuth2 访问令牌的主要内容,如果未能解决你的问题,请参考以下文章

Google Analytics API - 通过身份验证后无法添加服务

从 API 获取 Google Analytics“访客流量”数据

以 XML/JSON 格式返回 Google Analytics Reporting API 结果

如何通过 Google Analytics API 获取 Google Ads 关键字和广告内容

获取 Google Analytics API token Google_Client getAccessToken 返回 null 空。

Google Analytics 报告 API - 权限不足 403