【问题标题】:How to authorize the google-api-ruby-client?如何授权 google-api-ruby-client?
【发布时间】:2016-11-01 20:14:38
【问题描述】:

我正在按照此处的基本用法示例使 google-api-ruby-client gem 正常工作:基本用法

require 'google/apis/drive_v2'

Drive = Google::Apis::DriveV2 # Alias the module
drive = Drive::DriveService.new
drive.authorization = ... # See Googleauth or Signet libraries

# Search for files in Drive (first page only)
files = drive.list_files(q: "title contains 'finances'")
files.items.each do |file|
  puts file.title
end

我被困的地方是drive.authorization。我已经通过 gem omniauth-google-oauth2 为用户获得了授权令牌。如何将该令牌与 google-api-ruby-client 一起使用?

【问题讨论】:

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


    【解决方案1】:

    与其他答案类似,我采用了这种方法,其中使用了存储身份验证和刷新令牌的模型,从该逻辑中抽象出 API 交互。

    # Manages access tokens for users when using Google APIs
    #
    # Usage:
    # require 'google/apis/gmail_v1'
    # Gmail = Google::Apis::GmailV1 # Alias the module
    # service = Gmail::GmailService.new
    # service.authorization = GoogleOauth2Authorization.new user
    # service.list_user_messages(user.email)
    #
    # See also:
    # https://github.com/google/google-api-ruby-client/issues/296
    class GoogleOauth2Authorization
      attr_reader :user
    
      def initialize(user)
        @user = user
      end
    
      def apply!(headers)
        headers['Authorization'] = "Bearer #{token}"
      end
    
      def token
        refresh! if user.provider_token_expires_at.past?
        user.provider_access_token
      end
    
      private
    
      def refresh!
        new_token = oauth_access_token(
          user.provider_access_token,
          user.provider_refresh_token
        ).refresh!
        if new_token.present?
          user.update(
            provider_access_token: new_token.token,
            provider_token_expires_at: Time.zone.at(new_token.expires_at),
            provider_refresh_token: new_token.refresh_token
          )
        end
        user
      end
    
      def oauth_access_token(access_token, refresh_token)
        OAuth2::AccessToken.new(
          oauth_strategy.client,
          access_token,
          refresh_token: refresh_token
        )
      end
    
      def oauth_strategy
        OmniAuth::Strategies::GoogleOauth2.new(
          nil,
          Rails.application.credentials.oauth[:google_id],
          Rails.application.credentials.oauth[:google_secret]
        )
      end
    end
    

    【讨论】:

      【解决方案2】:

      我也被卡住了。 IMO Google 应该在他们的文档中更详细地说明,特别是因为我们所要做的只是添加一个请求标头......

      无论如何,这是一个例子。

      #
      # Note I don't think we always have to define a class with such a conflict-prone name. 
      # An anonymous class defined before every single API call should be also fine.
      #
      module Google
        class AccessToken
          attr_reader :token
          def initialize(token)
            @token = token
          end
      
          def apply!(headers)
            headers['Authorization'] = "Bearer #{@token}"
          end
        end
      end
      
      Drive = Google::Apis::DriveV2
      drive = Drive::DriveService.new
      drive.authorization = Google::AccessToken.new your_token
      

      参考:https://github.com/google/google-api-ruby-client/issues/296

      【讨论】:

      • 我会把这个模块放在 helper 文件夹中吗?我想 Rails 的魔法将允许在任何地方使用这些模块?
      猜你喜欢
      • 2011-11-21
      • 1970-01-01
      • 2023-03-15
      • 1970-01-01
      • 1970-01-01
      • 2017-05-16
      • 1970-01-01
      • 1970-01-01
      • 2012-04-16
      相关资源
      最近更新 更多