如何授权google-api-ruby-client?

时间:2022-01-29 15:24:14

I'm working to get the google-api-ruby-client gem working following the basic usage example here: Basic usage

我正在努力让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

Where I'm stuck is drive.authorization. I have an authorized token already for the user via the gem omniauth-google-oauth2. How do I use that token with google-api-ruby-client?

我被困的地方是drive.authorization。我已经通过gem omniauth-google-oauth2为用户提供了一个授权令牌。如何在google-api-ruby-client中使用该令牌?

Thanks

3 个解决方案

#1


1  

It depends on your app (app interacts with google only or also users' drives) so maybe start here: https://developers.google.com/api-client-library/ruby/guide/aaa_overview

这取决于您的应用(应用仅与谷歌或用户的驱动器进行互动),所以可以从这里开始:https://developers.google.com/api-client-library/ruby/guide/aaa_overview

#2


2  

I too was stuck. IMO Google should have more elaborated in their documents, especially since all we had to do was just adding one request header...

我也被卡住了。 IMO谷歌应该在他们的文档中有更详细的阐述,特别是因为我们所要做的只是添加一个请求标题...

Anyway, here is one example.

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

#
# 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

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

#3


0  

Similarly to other answers I followed this approach, where the model storing the auth and refresh tokens is used, abstracting API interactions from that logic.

与其他答案类似,我遵循这种方法,其中使用存储auth和刷新令牌的模型,从该逻辑中抽象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

#1


1  

It depends on your app (app interacts with google only or also users' drives) so maybe start here: https://developers.google.com/api-client-library/ruby/guide/aaa_overview

这取决于您的应用(应用仅与谷歌或用户的驱动器进行互动),所以可以从这里开始:https://developers.google.com/api-client-library/ruby/guide/aaa_overview

#2


2  

I too was stuck. IMO Google should have more elaborated in their documents, especially since all we had to do was just adding one request header...

我也被卡住了。 IMO谷歌应该在他们的文档中有更详细的阐述,特别是因为我们所要做的只是添加一个请求标题...

Anyway, here is one example.

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

#
# 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

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

#3


0  

Similarly to other answers I followed this approach, where the model storing the auth and refresh tokens is used, abstracting API interactions from that logic.

与其他答案类似,我遵循这种方法,其中使用存储auth和刷新令牌的模型,从该逻辑中抽象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