首页 > 解决方案 > Google API 服务器到服务器通信不起作用(Ruby 实现)

问题描述

我已按照所有步骤设置域范围的授权(https://developers.google.com/admin-sdk/reports/v1/guides/delegation)并点击此链接(https://developers .google.com/identity/protocols/OAuth2ServiceAccount#delegatingauthority),我最终在 Ruby 中创建了这个类。

class Gsuite::ServiceAccount

def initialize(person: nil)
end 

def authorized_client
      Google::Auth::ServiceAccountCredentials.make_creds(
    authorizer = Google::Auth::ServiceAccountCredentials.make_creds(
      json_key_io: StringIO.new(File.read AppConfig[:gsuite_service_account] 
 [:credentials_file]),
      scope: AppConfig[:gsuite_service_account][:scope])
    client = authorizer.fetch_access_token!
  end
end

这个类返回我这个哈希

{"access_token"=>"a_long_token_string_here", "expires_in"=>3600, "token_type"=>"Bearer"}

然后,我创建了这个方法(在我的 Admin 类中)来连接到 Gmail 服务

def gsuite_client_access
    @client ||= Gsuite::ServiceAccount.new(person: self.email.to_s).authorized_client
    authorized_client = Google::Apis::GmailV1::GmailService.new
    authorized_client.authorization = @client
    authorized_client
  end

因此,当我尝试在代码的另一部分中使用此行列出我的 Gmail 邮件时

inbox = current_admin.gsuite_client_access.list_user_messages('me', max_results: 10)

我收到以下错误消息 =>

Sending HTTP get https://www.googleapis.com/gmail/v1/users/me/messages?maxResults=10
401
#<Hurley::Response GET https://www.googleapis.com/gmail/v1/users/me/messages?maxResults=10 == 401 (238 bytes) 645ms>
Caught error Unauthorized
Error - #<Google::Apis::AuthorizationError: Unauthorized>

Retrying after authentication failure
Google::Apis::AuthorizationError: Unauthorized

任何想法这里缺少什么?

标签: rubygoogle-apigmailgmail-apigoogle-api-ruby-client

解决方案


最后,我让它工作了。事实证明,您需要使用此行来使用 sub 方法来“模拟用户”才能连接。

authorizer.sub = @person

而且,为了您的高兴,这里是用于阅读 Gmail 邮件的更新测试代码,因此您可以按照自己的意愿使用它。只需记住将 credentials.json 文件保存在您的项目文件夹中以使其工作并使用您在 GSuite 仪表板中添加的相同范围。

class Gsuite::ServiceAccount

  def initialize(person: nil)
    @person = person
  end

  def read_messages
    client = service_account_access
    inbox = client.list_user_messages(@person, max_results: 5, label_ids: "INBOX" )
    if inbox.result_size_estimate.nonzero?
      inbox.messages.each do |message|
        response = client.get_user_message(@person, message.id)
      end
    end
  end

private

  def service_account_access
    token = authorized_client
    client = Signet::OAuth2::Client.new(access_token: token['access_token'])
    client.expires_in = Time.current + token["expires_in"]
    auth_client = Google::Apis::GmailV1::GmailService.new
    auth_client.authorization = client
    auth_client
  end

  def authorized_client
    authorizer = Google::Auth::ServiceAccountCredentials.make_creds(
      json_key_io: StringIO.new(File.read AppConfig[:credentials_file]),
      scope: AppConfig[:gsuite_scope]).dup
    authorizer.sub = @person
    authorizer.fetch_access_token!
  end
end

推荐阅读