9

我一直無法找到這個在線答案 - 除了使用Google+登錄按鈕,我不想在這一點上使用,因爲我不想進入Javascript,如果我不想不必。Rails,OmniAuth,google_oauth2,google-api-client,Moments.insert ... 401未經授權...爲什麼?

我有一個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 

我也試圖與

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) 

,但沒有運氣更換

client.authorization.access_token = self.access_token 

我認爲這個問題要麼有做:

  1. OmniAuth不發出request_visible_actions到谷歌正常
  2. 我不要設置在谷歌:: APIClient對象正確

令牌我已經使用以下資源得到了這些,但我正式卡住了:

任何想法,將不勝感激!

+0

我有這個問題,我還沒有運氣。 – cicloon 2013-06-25 11:50:01

回答

0

在API控制檯中,您是否註冊爲Web應用程序或已安裝的應用程序? 我認爲你的情況你必須選擇已安裝的應用程序,以便令牌在用戶不在線時有效。

+0

我可以列出具有相同配置的活動,所以我猜它與此無關。 – cicloon 2013-06-25 15:19:10

3

這裏是我的web應用程序使用'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