【问题标题】:Rails, OmniAuth, google_oauth2, google-api-client, Moments.insert... 401 unauthorized... why?Rails、OmniAuth、google_oauth2、google-api-client、Moments.insert... 401 未经授权... 为什么?
【发布时间】:2023-04-11 10:23:01
【问题描述】:

我无法在网上找到答案——除了使用 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 对象中正确设置令牌

我已经使用以下资源做到了这一点,但我被正式卡住了:

任何想法都将不胜感激!

【问题讨论】:

  • 我也遇到了同样的问题,我还没有运气。

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


【解决方案1】:

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

【讨论】:

  • 我可以列出具有相同配置的活动,所以我猜它与此无关。
【解决方案2】:

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

【讨论】:

    【解决方案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
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-06-24
      • 1970-01-01
      • 2013-06-15
      • 1970-01-01
      • 2011-08-02
      • 2012-04-04
      • 2013-10-11
      • 1970-01-01
      相关资源
      最近更新 更多