Rails,OmniAuth,google_oauth2,google-api-client,Moments.insert ...... 401未经授权......为什么?

时间:2013-05-09 02:12:29

标签: ruby-on-rails ruby-on-rails-3.2 omniauth google-api-client

我无法在网上找到答案 - 除了使用Google+登录按钮,此时我不想使用,因为我不想进入Javascript,如果我不必。

我有一个Ruby on Rails应用程序(ruby v1.9.3,rails v3.2.13),其中我已经连接了OmniAuth并且我正在使用google_oauth2 gem与Google +集成。

我的简单目标是允许用户通过Google+进行身份验证,授予对我的Google API项目的访问权限,然后使用google-api-client gem向Google+用户的保险库发布片刻。

我已经设置了Google API项目,为Web应用程序创建了OAuth 2.0,并启用了Google+ API服务。

我已经使用以下提供程序设置了OmniAuth,并且我添加了request_visible_actions选项以允许我发布(我认为这是正确的但是没有看到我在网上查看的任何代码示例中使用过的... ):

provider :google_oauth2, CLIENT_ID, CLIENT_SECRET, {
    access_type: 'offline',
    scope: 'userinfo.email,userinfo.profile,plus.me,https://www.googleapis.com/auth/plus.login',
    request_visible_actions: 'http://schemas.google.com/AddActivity',
    redirect_uri: 'http://localhost/auth/google_oauth2/callback'
}

当我将用户重定向到/ auth / google_oauth2时,它会将用户发送到Google+以授权我的应用,当用户批准时,它会返回我的回调,我可以在其中访问request.env [“omniauth.auth”]并且它包含我期望的所有信息,包括令牌,电子邮件地址等。我正在存储来自auth [“credentials”] [“token”]的access_token。

到目前为止一切顺利,对吧?

当我尝试使用以下代码发布时刻时,我遇到一个异常,表示401未经授权的错误。

client = Google::APIClient.new

client.authorization.access_token = self.access_token

plus = client.discovered_api('plus', 'v1')

moment = {
    :type => 'http://schemas.google.com/AddActivity',
    :target => { :id => Time.now.to_i.to_s,
               :description => message,
               :name => message
    }
}

# post a moment/activity to the vault/profile
req_opts = { :api_method => plus.moments.insert,
             :parameters => { :collection => 'vault', :userId => 'me', },
             :body_object => moment
}

response = client.execute!(req_opts).body

我也试过替换

client.authorization.access_token = self.access_token

credentials = Hash.new
credentials[:access_token] = self.access_token
credentials[:refresh_token] = self.refresh_token
credentials[:expires_at] = self.expires_at
client.authorization.update_token!(credentials)

但没有运气。

我认为这个问题要么与:

有关
  1. OmniAuth未正确向Google发送request_visible_actions
  2. 我未正确设置Google :: APIClient对象中的令牌
  3. 我已经使用以下资源做到这一点,但我正式陷入困境:

    任何想法都将不胜感激!

3 个答案:

答案 0 :(得分:3)

以下是我使用'omniauth-google-oauth2'和'google-api-client'在网络应用中运行的代码。此示例代码使用日历API,但我想这对您有用。

require 'google/api_client'

class Calendar
  def initialize(user)
    @user = user
  end

  def events
    result = api_client.execute(:api_method => calendar.events.list,
                            :parameters => {'calendarId' => 'primary'},
                            :authorization => user_credentials)

    result.data
  end

  private

  def api_client
    @client ||= begin
      client = Google::APIClient.new(application_name: 'xxx', application_version: '0.0.1')
      client.authorization.client_id = ENV["GOOGLE_KEY"]
      client.authorization.client_secret = ENV["GOOGLE_SECRET"]
      client.authorization.scope = 'https://www.googleapis.com/auth/calendar'
      client
    end
  end

  def calendar
    @calendar ||= api_client.discovered_api('calendar', 'v3')
  end

  def user_credentials
    auth = api_client.authorization.dup
    # @user.credentials is an OmniAuth::AuthHash  cerated from request.env['omniauth.auth']['credentials']
    auth.update_token!(access_token: @user.credentials.token) 
    auth
  end
end

答案 1 :(得分:0)

在API控制台中,您是注册为Web应用程序还是已安装的应用程序? 我认为对于您的情况,您必须选择已安装的应用程序,以便在用户不在线时令牌有效。

答案 2 :(得分:0)

尝试使用plus.login更改https://www.googleapis.com/auth/plus.login。它以相同的设置为我工作。