Google API服务器到服务器的通信不起作用(Ruby实现)
我已按照所有步骤设置了域范围的授权( https://developers.google.com/identity/protocols/OAuth2ServiceAccount#delegatingauthority ),我最终在Ruby中创建了此类.>
I have followed all the steps to set up a Domain-Wide Delegation of Authority (https://developers.google.com/admin-sdk/reports/v1/guides/delegation) and followed this link too (https://developers.google.com/identity/protocols/OAuth2ServiceAccount#delegatingauthority) and I ended up creating this class in 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服务
Then, I've created this method (within my Admin class) to connect to Gmail Service
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邮件时
So, when I try to list my Gmail Messages with this line in another part of the code
inbox = current_admin.gsuite_client_access.list_user_messages('me', max_results: 10)
我收到以下错误消息=>
I get the following error message =>
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
有什么想法吗?
最后,我开始使用它了.事实证明,您需要使用此行对模拟用户"使用子方法才能进行连接.
Finally, I got it working. Turns out, you need to use this line to use the sub method to the "impersonated user" to be able to connect.
authorizer.sub = @person
而且,令您高兴的是,这是用于阅读Gmail邮件的更新的测试代码,以便您在有需要的时候使用.只需记住将credits.json文件保存在项目文件夹中以使其正常工作,并使用与在GSuite仪表板中添加的作用域相同的作用域即可.
And, for your delight, here is the updated test code for reading Gmail messages so you can follow in case you want to use it. Just remember to save the credentials.json file in your project folder to make it work and use the same scope you added in the GSuite Dashboard.
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