Search code examples
ruby-on-railsrubygoogle-api-ruby-client

Google Ruby API Client redirect_uri_mismatch error


I'm trying to use Google's API to sign up and log in users to my rails webapp. I've been playing around with the authentication, but I'm getting stuck on this error after I get the authorization code.

Here's what I'm trying to do:

path = Rails.root.to_s + PATH_TO_JSON_FILENAME_FROM_GOOGLE_API

client_secrets = Google::APIClient::ClientSecrets.load(path)

auth_client = client_secrets.to_authorization

auth_client.update!(
  :scope => 'https://www.googleapis.com/auth/drive.metadata.readonly',
  :redirect_uri => REDIRECT_URI

)

auth_client.code = ACCESS_CODE_RETURNED_BY_GOOGLE_WHEN_USER_LOGS_IN

auth_client.fetch_access_token!

A few questions:

  1. All I really want to be able to pull is the users name, and their email address. I'm unclear on what the proper value for :scope should be.
  2. For the redirect_uri I'm setting it to one of the redirect uri's that are in my Google API console. Something along the lines of http://localhost:3000/auth/callback. Despite this, I'm getting the following json response:

    { "error" : "redirect_uri_mismatch" }

Thoughts on what I might be doing wrong here?


Solution

  • Finally figured this out. I needed to set the redirect_uri to postmessage, because that's how I originally requested the authorization code. Here's my complete solution:

    I load the Google Authentication library with the following:

    function start() {
      gapi.load('auth2', function() {
        auth2 = gapi.auth2.init({
          client_id: 'MY_CLIENT_ID',
        });
      });
    };
    

    I created an HTML button, which on click makes the call to the following function:

    function(e){
        e.preventDefault();    
        auth2.grantOfflineAccess({'redirect_uri': 'postmessage'}).then(this.signInCallback);
    },
    

    Right now the signInCallback function is just logging my authorization code so I can test out the ruby server code I'm writing:

    function(authResult) {
        console.log(authResult.code);
    }
    

    Here's what my ruby file looks like:

    client = Google::APIClient.new
    client.authorization.client_id = MY_CLIENT_ID
    client.authorization.client_secret = MY_CLIENT_SECRET
    client.authorization.redirect_uri = "postmessage"
    client.authorization.code = CODE_THAT_WAS_LOGGED_TO_CONSOLE
    client.authorization.fetch_access_token!
    

    A little more info: you have to use 'postmessage' calling grantOfflineAccess. I tried putting in one of the actual redirect uri's from my developer console, and it didn't like that (see this SO question for more). What I figured out is that if you do this, then you need to do the same thing on the server side when you try to exchange the authorization code for an access token.