9

Tôi không thể tìm thấy câu trả lời cho trực tuyến này - ngoài việc sử dụng nút Đăng nhập bằng Google+ mà tôi không muốn sử dụng vào thời điểm này vì tôi không muốn tham gia Javascript nếu tôi không không phải.Rails, OmniAuth, google_oauth2, google-api-client, Moments.insert ... 401 trái phép ... tại sao?

Tôi có ứng dụng Ruby on Rails (ruby v1.9.3, ray v3.2.13) trong đó tôi đã kết nối OmniAuth và tôi đang sử dụng đá quý google_oauth2 để tích hợp với Google+.

Mục tiêu đơn giản của tôi là cho phép người dùng xác thực với Google+, cấp quyền truy cập vào dự án Google API của tôi và sau đó có thể đăng một khoảnh khắc lên hầm của người dùng Google+ bằng cách sử dụng đá quý google-api-client.

Tôi đã thiết lập Dự án Google API của mình, đã tạo OAuth 2.0 cho ứng dụng web và bật dịch vụ API Google+.

Tôi có thiết lập OmniAuth với nhà cung cấp sau và tôi đã thêm tùy chọn request_visible_actions để cho phép tôi đăng (Tôi nghĩ điều này là chính xác nhưng chưa thấy điều này được sử dụng từ bất kỳ ví dụ mã nào mà tôi đã xem trực tuyến .. .):

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

khi tôi chuyển hướng người dùng của tôi đến/auth/google_oauth2, nó sẽ gửi người dùng Google+ cho phép ứng dụng của tôi và khi người dùng chấp thuận, nó sẽ trả về để gọi lại của tôi, nơi tôi có thể truy cập vào request.env ["omniauth.auth"] và nó có tất cả thông tin tôi mong đợi, bao gồm mã thông báo, địa chỉ email, v.v. Tôi lưu trữ access_token từ auth ["credentials"] ["token"].

Cho đến nay rất tốt, phải không?

Khi tôi cố gắng đăng thời điểm bằng mã sau, tôi gặp phải một ngoại lệ cho biết lỗi trái phép 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 

Tôi cũng đã cố gắng thay thế

client.authorization.access_token = self.access_token 

với

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) 

Nhưng không may mắn.

Tôi nghĩ vấn đề hoặc đã làm với:

  1. OmniAuth không ban hành request_visible_actions đến Google một cách chính xác
  2. nhớ không thiết lập các thẻ trong đối tượng của Google :: APIClient đúng

Tôi đã sử dụng các tài nguyên sau đây nhưng tôi đã chính thức bị kẹt:

ý tưởng Bất kỳ sẽ được đánh giá!

+0

Tôi gặp vấn đề tương tự, tôi chưa có bất kỳ sự may mắn nào. – cicloon

Trả lời

0

Trong bảng điều khiển API, bạn đã đăng ký làm ứng dụng web hay ứng dụng đã cài đặt chưa? Tôi nghĩ cho trường hợp của bạn, bạn phải chọn ứng dụng đã cài đặt, để mã thông báo hợp lệ nếu người dùng không trực tuyến.

+0

Tôi có thể liệt kê các hoạt động, với cùng cấu hình, vì vậy tôi đoán nó không liên quan đến hoạt động đó. – cicloon

3

Đây là mã làm việc của tôi từ ứng dụng web sử dụng 'omniauth-google-oauth2' cùng với 'google-api-client'. Mã mẫu này sử dụng API lịch, nhưng tôi đoán nó sẽ làm việc cho bạn.

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