intuit / oauth-jsclient

Intuit's NodeJS OAuth client provides a set of methods to make it easier to work with OAuth2.0 and Open ID
https://developer.intuit.com/
Apache License 2.0
120 stars 154 forks source link

login popup throws cross-origin error #84

Closed dan-yave closed 4 years ago

dan-yave commented 4 years ago

The popup throws a DOMException every iteration of the setInterval function when it runs the following check (line 102 of index.html in sample app) if (win.document.URL.indexOf("code") != -1) {

It fails on both ngrok URL or localhost

error error_msg

This check violates the same origin policy https://developer.mozilla.org/en-US/docs/Web/Security/Same-origin_policy

To reproduce simply run the sample and open dev tools on chrome and watch the console get spammed. Somehow the code works and after I authenticate it closes the frame, but i can not get it to work at all in my Vue Js SPA as it does not allow the check.

Is there any other way to be notified on successful login to close the window? Does Intuit provide web-hooks?

thanks

abisalehalliprasan commented 4 years ago

@dan-yave The sample application opens the Authorize URL using the window object. So we use a polling approach to check if the popup window contains a code

if (win.document.URL.indexOf("code") != -1) {close the window after the redirect is successful}. 

Instead a better approach to handle this would be to pass the path(route) which should then redirect using the express framework as: ( will provide an example in the next release )

app.get('/connect_to_quickbooks', urlencodedParser, function(req,res) {

  oauthClient = new OAuthClient({
    clientId: 'enter the clientID',
    clientSecret: 'enter the clientSecret',
    environment: 'sandbox' || 'production',
    redirectUri: 'enter the redirectURI'     
  });

  const authUri = oauthClient.authorizeUri({scope:[OAuthClient.scopes.Accounting],state:'intuit-test'});
  res.redirect(authUri);

});

Let's say for the sake of example, your redirect URI looks like :

https://89606f74.ngrok.io/callback

Upon successful redirect your callback route in the app(framework) will get called :

/**
 * Handle the callback to extract the `Auth Code` and exchange them for `Bearer-Tokens`
 */
app.get('/callback', function(req, res) {

    oauthClient.createToken(req.url)
       .then(function(authResponse) {
             oauth2_token_json = JSON.stringify(authResponse.getJson(), null,2);
             res.redirect('/');
         })
        .catch(function(e) {
             console.error(e);
         });

});

hereupon successful redirect to the redirectUri the window would redirect, wherein you do not have to keep polling as shown in the current sample. ( the beauty with frameworks )

So it basically depends on the framework you are using ( As in your case with Vue.js also it should be similar )

If you are not using a framework and also polling is not an option, You could see if this post is of any help.

Hope this helps!

dan-yave commented 4 years ago

Thank you @abisalehalliprasan I'll give it a try. I can see how this would work on a static or server-side rendered site, but I'm not sure on a SPA site like Vue.

Thanks again for your response Dan

abisalehalliprasan commented 4 years ago

For what its worth. I did take a look at one of the popular OAuth libraries built in Vue for SPA's. It looks like polling the popup window is used ref : stackoverflow article

I tried to see if we do have any SPA examples, but we have a Python Sample on our Github, but that too uses a Django framework. Adding it here if it helps your development in anyway: SampleOAuth2_UsingPythonClient

dan-yave commented 4 years ago

cool - thank you! ill go ahead and close this out