How can I authorize a Google Service Account without the default credentials file?

前端 未结 3 1777
爱一瞬间的悲伤
爱一瞬间的悲伤 2021-02-04 12:20

I have a Google Service Account that my app uses to retrieve data from Google Analytics.

When I created the account I downloaded a client_secrets file with

3条回答
  •  孤独总比滥情好
    2021-02-04 12:43

    Since this is one of the main results that returns when searching google for "google service credentials ruby," I thought I would add my very recent experience to the list of possible answers.

    Though you can do the method mentioned in the first answer, I found an alternate solution that works well with Heroku. I know it has been somewhat mentioned in another post, but the key thing that was left out was how to properly store the full GOOGLE_APPLICATION_CREDENTIALS .json file so that it can all be kept within one env on Heroku and not have special characters blow up your app when tryin to

    I detail my steps below:

    1. Obtain your GOOGLE_APPLICATION_CREDENTIALS json file by following Google's instructions here: Getting Started with Authentication
    2. That will, of course, contain a json object with all the spaces, line returns, and quotations that heroku simply doesn't need. So, strip out all spaces and line breaks...AND PAY ATTENTION HERE -> EXCEPT FOR THE LINE BREAKS WITHIN THE 'BEGIN PRIVATE KEY' SEGMENT. Basically turn the json into one long string. Use whatever method you feel comfortable with.
    3. Once you have a single line json file with whitespace and line breaks removed, you will need to add it to Heroku by running the following command:

      heroku config:set GOOGLE_APPLICATION_CREDENTIALS="$(< /Users/whoever/Downloads/[CREDENTIAL_JSON_FILENAME].json)" --app your-app
      
    4. For my situation, I needed to have the service account available on initialization, so I placed this in an initializer in my rails app:

      GOOGLE_SERVICE_ACCOUNT_CREDENTIALS=Google::Auth::ServiceAccountCredentials.make_creds(
        json_key_io: StringIO.new(ENV['GOOGLE_APPLICATION_CREDENTIALS'])
      )
      

    Notice the StringIO.new() method. the #make_creds wants a file. So, fake it as such by using StringIO.new.

    This method works perfectly.

    If you need this to work differently on your local machine, you can always store the .json somewhere in the project and reference it through a file location string. Here is my full initializer:

    require 'googleauth'
    
    #https://www.rubydoc.info/github/google/google-auth-library-ruby/Google/Auth/ServiceAccountCredentials 
    if Rails.env == "test"
      GOOGLE_SERVICE_ACCOUNT_CREDENTIALS = 
    Google::Auth::ServiceAccountCredentials.make_creds(
        json_key_io: File.open('lib/google/google_application_credentials.json')
      ) 
    elsif Rails.env != "development"
        GOOGLE_SERVICE_ACCOUNT_CREDENTIALS = 
    Google::Auth::ServiceAccountCredentials.make_creds(
        json_key_io: StringIO.new(ENV['GOOGLE_APPLICATION_CREDENTIALS'])
      ) 
    end
    

    If you are using a gem like dotenv you can store the formatted json string as an ENV or you can just reference the file location in the ENV

    I hope this helps someone.

提交回复
热议问题