9

Nie mogę znaleźć odpowiedzi na to online - oprócz użycia przycisku Zaloguj się w Google+, którego nie chcę teraz używać, ponieważ nie chcę korzystać z JavaScriptu, jeśli nie trzeba.Railsy, ​​OmniAuth, google_oauth2, google-api-client, Moments.insert ... 401 nieautoryzowane ... dlaczego?

Mam aplikację Ruby on Rails (ruby v1.9.3, rails v3.2.13), w której podpiąłem OmniAuth i używam gem google_oauth2 do integracji z Google+.

Moim prostym celem jest umożliwienie użytkownikowi uwierzytelnienia się w Google+, przyznanie dostępu do mojego projektu interfejsu API Google, a następnie wysłanie chwili na skarbiec użytkownika Google+ za pomocą gem google-api-client.

Mam już skonfigurowany projekt Google API, utworzyłem OAuth 2.0 dla aplikacji internetowych i włączyłem usługę Google+ API.

Mam konfigurację OmniAuth z następującym dostawcą i dodałem opcję request_visible_actions, aby umożliwić mi publikowanie (uważam, że jest to poprawne, ale nie widziałem tego używanego z przykładów kodu, które obejrzałem online .. .):

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' 
} 

kiedy przekierowanie użytkownika do mojego/auth/google_oauth2, wysyła użytkownikowi Google+ autoryzować moją aplikację i kiedy użytkownik zatwierdza, zwraca do mojej zwrotnego, gdzie mogę uzyskać dostęp do request.env ["omniauth.auth"] i zawiera wszystkie informacje, których mógłbym się spodziewać, w tym tokeny, adres e-mail itp. Przechowuję access_token od auth ["credentials"] ["token"].

Jak dotąd tak dobrze, prawda?

Kiedy próbuję opublikować moment za pomocą następującego kodu, pojawia się wyjątek wskazujący 401 nieautoryzowany błąd.

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 

Próbowałem również zastąpienie

client.authorization.access_token = self.access_token 

z

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) 

ale bez powodzenia.

Myślę, że kwestia czy ma do czynienia z:

  1. OmniAuth nie wydając request_visible_actions do Google poprawnie
  2. Me nie ustawienie token w obiekcie Google :: APIClient prawidłowo

Zrobiłem to za pomocą następujących zasobów, ale oficjalnie utknąłem:

jakieś pomysły będą mile widziane!

+0

Mam ten sam problem, jeszcze nie miałem szczęścia. – cicloon

Odpowiedz

0

Czy w konsoli API zarejestrowałeś się jako aplikacja internetowa lub zainstalowana aplikacja? Myślę, że w twoim przypadku musisz wybrać zainstalowaną aplikację, aby token był ważny, jeśli użytkownik nie jest online.

+0

Mogę wyświetlić listę czynności z tą samą konfiguracją, więc domyślam się, że nie jest z tym związana. – cicloon

3

Oto mój działający kod z aplikacji internetowej używającej "omniauth-google-oauth2" oraz "google-api-client". Ten przykładowy kod wykorzystuje interfejs API kalendarza, ale domyślam się, że zadziała.

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