mondora / asteroid

An alternative client for a Meteor backend
MIT License
734 stars 101 forks source link

redirect_uri_mismatch with google login in chrome extension #69

Closed nivekuil closed 9 years ago

nivekuil commented 9 years ago

I've read through the other threads on the issue tracker, and while some are very similar, I haven't been able to solve my problem. Here's the code I have so far:

background.js

var url = 'localhost:3000';
var ddp = new Asteroid(url);

popup.js

var ddp = chrome.extension.getBackgroundPage().ddp;
document.getElementById("login-with-google") //button in popup.html
  .addEventListener("click", function() {
    ddp.loginWithGoogle();
  });

So when I click the button in the popup, the google auth popup appears, I choose which account to use, and it closes without a hitch. Nothing printed in the console in the popup or background pages. On the server, though, I get this error:

W20150703-12:01:29.904(-7) (oauth_server.js:398) Error in OAuth Server: Failed to complete OAuth handshake with Google. failed [400] {   "error" : "redirect_uri_mismatch" }

My manifest.json:

{
  "manifest_version": 2,

  "name": "blahblah",
  "description": "blahblahblah",
  "version": "0.0.1",

  "background": {
    "scripts": ["lib/bower_components/ddp.js/src/ddp.js",
                "lib/bower_components/q/q.js",
                "lib/bower_components/asteroid/dist/asteroid.browser.js",
                "lib/bower_components/asteroid/dist/plugins/google-login.js",
                "background.js"]
  },

  "browser_action": {
    "default_icon": "icon.png",
    "default_popup": "popup.html"
  },

  "permissions": [
    "activeTab",
    "identity",
    "geolocation",
    "tabs",
    "storage"
  ]
}

And in my Google API console, my redirect urls:

http://localhost:3000/_oauth/google?close
http://localhost:3000/_oauth/google/
http://localhost:3000/_oauth/google

The authentication works fine from a regular meteor client, but not from the chrome extension using asteroid. I've also added mondora:asteroid to the meteor server. Any help is appreciated!

pscanf commented 9 years ago

Try using asteroid.chrome.js instead of asteroid.browser.js, that might do the trick (it's the version specifically compiled for chrome extensions).

If that is not enough to make it work, let me know and we'll debug it further (I remember seeing that error somewhere and, iirc, it was due to a misconfiguration of the Google App).

Cheers :-)

nivekuil commented 9 years ago

Can't believe I missed that little detail! But unfortunately, it's still the same error - the only difference I see is that now the login dialog opens as a new tab instead of a popup window. Thanks for your help!

pscanf commented 9 years ago

Mmh, then it's probably the same problem I had encountered. The correct redirect_uri in google's console is http://localhost:3000/_oauth/google, so try setting that. It might be that google takes a bit of time (10m or so) to change the configuration, so you might need to wait a bit.

I can't think of anything else right now. You could try testing the login with another oauth provider (e.g. facebook) to see if the error still occurs.

Let me know

nivekuil commented 9 years ago

Yeah, I've had that in my redirect URI's along with two other possible forms. I'll test another oauth provider when I get some time tomorrow. Here's my popup.html for reference as well, it should be all of the code I have.

<head>
  <script src="lib/bower_components/ddp.js/src/ddp.js"></script>
  <script src="lib/bower_components/q/q.js"></script>
  <script src="lib/bower_components/asteroid/dist/asteroid.chrome.js"></script>
  <script src="lib/bower_components/asteroid/dist/plugins/google-login.js"></script>
  <script src="popup.js" defer></script>
  <link rel="stylesheet" type="text/css" href="popup.css"></script>
</head>
<body>
  <button id="login-with-google"> Login with Google </button>
</body>
nivekuil commented 9 years ago

Facebook login works with a regular meteor client, but within the extension, it's the same thing as with google. I get this error on the server:

Error in OAuth Server: Failed to complete OAuth handshake with Facebook. failed [400] {"error":{"message":"Error validating verification code. Please make sure your redirect_uri is identical to the one you used in the OAuth dialog request","type":"OAuthException","code":100}}
pscanf commented 9 years ago

It could be that calling the login function from the popup breaks it. Try calling it from the background.js by sending it a message when the user clicks on the popup button, and logging in upon receiving that message (see example).

nivekuil commented 9 years ago

I still get the same error with:

popup.js

chrome.runtime.sendMessage("login");

background.js

chrome.runtime.onMessage.addListener(function (request, sender, sendResponse) {
  var Ceres = new Asteroid("localhost:3000");
  Ceres.subscribe("meteor.loginServiceConfiguration").ready.then(function () {
    Ceres.loginWithFacebook();
  });
});
pscanf commented 9 years ago

Well, I have no idea what's going on! :smile: You could try setting a debug breakpoint around here to see what happens in detail. What's the redirect_uri that gets used? What does the loginUrl becomes?

nivekuil commented 9 years ago

console.log(query.redirect_uri);

http://localhost:3000/_oauth/google

console.log(loginUrl);

https://accounts.google.com/o/oauth2/auth?response_type=code&client_id=736256076958-2uepj34v76q7n7pgfuvfi30qlvtbpade.apps.googleusercontent.com&redirect_uri=http%3A%2F%2Flocalhost%3A3000%2F_oauth%2Fgoogle&state=eyJsb2dpblN0eWxlIjoicG9wdXAiLCJjcmVkZW50aWFsVG9rZW4iOiI4YTVhMjc5NjJjODQ0MzljYzE0Nzg5MWI4MGM2OWVjYyIsImlzQ29yZG92YSI6ZmFsc2V9&scope=openid%20email

The client_id it's using is the "Client ID for web application", which is the one that I have set in the server's ServiceConfiguration. There's also a client ID for chrome application - I changed the ServiceConfiguration to use that one instead, but I get an invalid client error.

W20150704-14:03:57.548(-7) (oauth_server.js:398) Error in OAuth Server: Failed to complete OAuth handshake with Google. failed [401] {   "error" : "invalid_client" }
pscanf commented 9 years ago

The two urls look correct. I don't follow you on the "Client ID for web application" thing: why do you have 2 client ids? Can you post your service configuration?

nivekuil commented 9 years ago

I believe that you need a separate client ID for chrome application to use the chrome identity api, which shouldn't be relevant here anyway. See here. Here's a screenshot of my google console: image And my service configuration:

ServiceConfiguration.configurations.upsert(

  { service: "google" },

  {
    $set: {
      clientId: "736256076958-2uepj34v76q7n7pgfuvfi30qlvtbpade.apps.googleusercontent.com",
      secret: "xxxxxxxxxxxx_xxxxxxxxxx"
    }
  }

);
pscanf commented 9 years ago

Ah ok, I didn't know that. Try setting also in the configuration "loginStyle": "popup", maybe that changes something.

nivekuil commented 9 years ago

Yep, that fixed it! Now I'm curious why this is necessary, though. Thanks for all your help!

pscanf commented 9 years ago

Well, lucky me, that was my last guess. :smile:

I remember some time ago (v0.9.2) meteor introduced two login flows, popup and redirect. Asteroid currently only supports the popup flow. Iirc if you don't specify anything in the configuration, meteor falls back to the popup flow as it was implemented pre-v0.9.2 in order to support old clients. Asteroid probably does not support that old method (I should look through the code to confirm it, but it's too late here :smile: ), so you need to specify that property.

Anyway, I'm glad we've solved it. :smiley: Cheers