This question is similar to How can I authorize a Google Service Account without the default credentials file? but specifically about how to use Rails' built in secrets/credentials functionality.
I realise it needs to be JSON but when I store credentials in a private method and pass that method to json_key_io
I get a NoMethodError
:
def call
auth = Google::Auth::ServiceAccountCredentials.make_creds(
json_key_io: credentials,
scope: Google::Apis::ClassroomV1::AUTH_CLASSROOM_ROSTERS
)
end
private
def credentials
@credentials ||= {
type: "service_account",
project_id: Rails.application.credentials.google[:project_id],
private_key_id: Rails.application.credentials.google[:private_key_id],
private_key: Rails.application.credentials.google[:private_key],
client_email: Rails.application.credentials.google[:client_email],
client_id: Rails.application.credentials.google[:client_id],
auth_uri: "https://accounts.google.com/o/oauth2/auth",
token_uri: "https://oauth2.googleapis.com/token",
auth_provider_x509_cert_url: "https://www.googleapis.com/oauth2/v1/certs",
client_x509_cert_url: Rails.application.credentials.google[:client_x509_cert_url],
}.to_json
end
NoMethodError (undefined method ``read' for "{\"type\":\"service_acco...
The key thing I was missing (as pointed out by miggitymac in this answer) is that the client is expecting an IO object (a file), not a string.
With the addition of StringIO.new
, this now works as expected:
def call
auth = Google::Auth::ServiceAccountCredentials.make_creds(
json_key_io: StringIO.new(credentials),
scope: Google::Apis::ClassroomV1::AUTH_CLASSROOM_ROSTERS
)
end
private
def credentials
@credentials ||= {
type: "service_account",
project_id: Rails.application.credentials.google[:project_id],
private_key_id: Rails.application.credentials.google[:private_key_id],
private_key: Rails.application.credentials.google[:private_key],
client_email: Rails.application.credentials.google[:client_email],
client_id: Rails.application.credentials.google[:client_id],
auth_uri: "https://accounts.google.com/o/oauth2/auth",
token_uri: "https://oauth2.googleapis.com/token",
auth_provider_x509_cert_url: "https://www.googleapis.com/oauth2/v1/certs",
client_x509_cert_url: Rails.application.credentials.google[:client_x509_cert_url],
}.to_json
end