Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to use the library in phonegap #10

Open
irfancue opened this issue Jun 27, 2012 · 20 comments
Open

How to use the library in phonegap #10

irfancue opened this issue Jun 27, 2012 · 20 comments

Comments

@irfancue
Copy link

Hey,

thank you for that library, but I cannot get it running in phongap using childbrowser and google api. Is this library not made for that usage? I am getting following error in the console: 06-27 02:10:21.050: E/Web Console(26018): Uncaught illegal access at file:///android_asset/www/js/jso.js:157

@andreassolberg
Copy link
Owner

I would be very interested in knowing and making sure that jso works with phonegap. However, I'm not sure exactly what is the problem here..

It seems that the problem is related to a security restriction that does not allow you to access localstorage from the childbrowser.

How do you use the childbrowser? Do you run the app itself in the childbrowser? I'm a bit surprised that the getToken() function is referred in the childbrowser, as I would expect users to only use the childbrowser for loading up the "OAuth Provider authorization endpoint".

@irfancue
Copy link
Author

Thank you for your response. I am running the app in the webview in Android. The childbrowser plugin is only (like you mentioned) for the "OAuth Provider authorization endpoint". It works fine without your library, but I would like to use your library.

With your library I do not have a possibility to open the authorization in the childbrowser. But even before, just after calling jso_configure the library calls the error described. I installed for Oauth 1 another library (jsOAuth-1.3.4.min.js) where I call the Authorize-Url like this:

window.plugins.childBrowser.showWebPage(url, { showLocationBar : false });

Then I handle location-changes of the childbrowser to see what the user did and to get tokens and parameters from the new url. At this point I close the childbrowser. It is only open to receive a request token. I can use that to do some more API calls for exchanging the Request token with the access token. Then I save the access token to the localstorage and use it for gettnig user data and other stuff.

My question is how your library can be used to do this magic for oauth2.

Thank you.

Irfan

@andreassolberg
Copy link
Owner

OK, what if I add support for registering a callback for 'opening the authorization url' instead of just redirecting the current window as I do now. That would help wouldn't it? Then you could open the authorization url only in the childbrowser.

Then how to capture the response when the user is redirected back in the childbrowser would be another question. I am not really sure as I have not worked with the childbrowser.

@irfancue
Copy link
Author

irfancue commented Jul 6, 2012

I think that might work. After opening the url in the childbrowser you can add a listener to location changes of the url. Extracting the parameters in the new url after redirection is how the response is fetched. 1. Authetication URL is opened 2. User gives his credentials 3. When Redirecting to callback url fetch url with new parameters and close childbrowser 4. Extract paramaters from url like request_token or verifier then get acces token the ajax way. This is how I made it right now.

@libbybaldwin
Copy link

How nice to see discussion just at the time I'm about to try it. I don't know if differences between OAuth 1 and 2 affect my past usage: OAuth 1 with the jsOAuth plugin by bytespider. For that use with Twitter / PhoneGap / Android, I knew the url that would come back to me on success, closed ChildBrowser window and returned to app. The bytespider jsOAuth plugin IIRC asked for token etc and cached for me, so after login, just used Twitter REST API like normal.

My comments may be too early since I haven't tried yours with my next project.

@libbybaldwin
Copy link

I may be where irfancue left off - successfully logged in, got to my app's redirect uri, but what I really want is control of the whole thing.. after successful auth I want to 'listen' for redirect uri and close the child browser. BUT - still have the tokens, and make my own posts and gets from the app.

Thinking of using childbrowser calls inside jso - which would make it a complete different type of plugin!

After auth, if I try to $.oajax() with in my app, it seems to want to start the auth process again.

Sorry if my thinking is all over the place - I'm very interested in getting this working.
jsOAuth plugin for OAuth1 used with child browser plugin for PhoneGap / Android:
https://github.com/libbybaldwin/applaud-tmt5p1-oauth-twitter

@ghost ghost assigned andreassolberg Jul 16, 2012
@andreassolberg
Copy link
Owner

Hi folks,
sorry about the lack of follow up last days.

I just started on a branch with a few changes that would make it easier to integrate with phonegap (I suppose)

  • I'm adding possibility of registering custom redirect handler, it would mean that you can very easily replace the redirect functionality with opening up a child browser.
  • I'm adding as well possibility of regstering an alternative storage from localstorage.
  • I'm adding exposing a function that you can call when the childbrowser is returning back to the app, including the accesstoken.

I'm on vacation and unfortunately cannot make any time estimate for when this is ready. But I'll keep you updated.

@irfancue
Copy link
Author

Hey Andreas,

first 2 bullets sound great. That will make it definitely possible to open the childbrowser. The last point is actually not that important: Normally you add a listener to changes of the location of the childbrowser. When the url changes you take that url, parse all the parameters in the new url and close the childbrowser wihtin this listener. So there is not really a need to add a callback as far as I know. But maybe there are use cases for that.

Enjoy your vacation.

Irfan

@irfancue
Copy link
Author

Hey libby,

OAuth 1 and OAuth 2 work very different.Twitter and LinkedIn work nice with bytespider. But there are no good libraries for OAuth 2 and no one that implents jQuery like usage. That makes this Plugin very interesting.

@andreassolberg
Copy link
Owner

Hi again. I've committed some more or less untested code to a branch 'phonegap'. I wrote some initial text describing how I expect it to be used here: https://github.com/andreassolberg/jso/tree/phonegap#using-jso-with-phonegap

If you are interested in testing it out feel free.

Regarding the last bullet point, I think that JSO should be able to parse the response to the callback, and feed it into its storage, and then let you use the $.oajax wrapper for getting your data. Here is some pseudocode:

// A listened that receives events when the URL of the childbrowser changes. I have
// noe idea how that looks like, but I would foresee something like this.
childbrowser.on('locationChange', function(childurl) {  

    // Are we really at the callback url?
    if (childurl.match(/does not match callback base url of service/)) return;

    // Feed JSO with the URL, and let it parse it.
    jso_checkfortoken('facebook', childurl);

    $.oajax({
        url: "https://graph.facebook.com/me/home",
        jso_provider: "facebook",
        jso_scopes: ["read_stream"],
        jso_allowia: true,
        dataType: 'json',
        success: function(data) {
            console.log("Response (facebook):");
            console.log(data);
        }
    });
});

@libbybaldwin
Copy link

Hi to you both. Thanks for the follow ups.

I'm currently not using jso, except for a modified parseQueryString(). All regarding oauth in my app is working! Perhaps OAuth2 is simpler than OAuth1 to manage 'by hand'.

This is my first use of OAuth 2 so learning lots, and now that I'm close to cleaning up my code, I can see the benefit of using a library, not to mention the re-use factor! so definitely interested in a PhoneGap version of jso.

It will be at least a week before I get back to this project, but up for testing, etc. Oh yeah - speaking at PhoneGap Day in Portland this Friday (very briefly) on my use of OAuth, OpenID and PhoneGap. Cheers!

@libbybaldwin
Copy link

I like that you're trying to support PhoneGap/ChildBrowser, not completely convinced of it happening cleanly.. I need to read through jso again now that I know OAuth2 a little better. (still - add ignorance disclaimer to the following)

Thanks for handling "#" now!

On a mobile device, I'm not sure yet that state is needed. I used device ID but also did fine with no state. To support something like multiple sign-in/users (rare but might be on something like tablet), state might be better as a unique user string. Maybe good form to use state in general. I see you use random number.

When the redirect is found, it would call .close() on the child browser.

Jso might be somewhat specific to FB's auth flow - could be generalized more to support other.

@andreassolberg
Copy link
Owner

I'm setting up phonegap (with iOS), and preparing a detailed guide on how to make it work. However I cannot promise any time for when it to be completed as I am on vacation.

@andreassolberg
Copy link
Owner

I've done some major updates to JSO and merged it into master, to better support a typical Phonegap setup.

I have also writted a detailed guide on exactly how to use JSO with phonegap.

I'd really appreciate some feedback on this. Thanks.

@libbybaldwin
Copy link

I'm using the phonegap branch, with some success. I can log in, close browser, send url to jso, etc. I pass the redirect url to jso_checkfortoken, no problem. But - in my homemade working library I specified non-expiring token like 'scope': "non-expiring", however I don't think jso is using this. Is it possible with jso_configure? I could probably dig deeper and figure out, but stopping for the day.

I am on Android, where childBrowser is much different than iOS. I have 3 small things I need to change in jso for Android 2.x.

@gwest7
Copy link

gwest7 commented Jan 15, 2013

Hi Andreas. We have spent some time finding a bug when logging into Facebook using JSO and Phonegap on BlackBerry. On iOS 5 and Android 2.3 the login process works well. On BlackBerry OS 5 the onLocationChange never triggers.

We found that the method 'jso_registerRedirectHandler' detaches the scope of the showWebPage function. What happens is the ChildBrowser takes us to FaceBook.com to log in, but after logging in the onLocationChange does not execute.

When we in jso.js replaced 'api_redirect' with 'window.plugins.childBrowser.showWebPage' the onLocationChange was called.

Other than that it all worked well. Great library.

@andreassolberg
Copy link
Owner

Thanks for the feedback. I've no possibility of verifying on blackberry. If you are able to send a pull request with a fix that is verified on all platforms it would be appreciated by both me and future users. Thanks.

@jdeveloper
Copy link

What if I want to open a new window in a desktop browser to login?

I i do jso.callbacks.redirect = jso.inappbrowser({}); and then jso.getToken() all works as expected but the window does not close, the 'loadstart' event isn't even triggered.

Tanks

@jdeveloper
Copy link

I have a solution for desktop browsers like so:

jso.callbacks.redirect = function(url, callback){
                function checkWindowUrl(window) {
                    var url = "error";
                    try{
                        url  = window.location.href;

                        if(window.location.hash != ''){
                            url += '#' + window.location.hash;
                        }
                    }catch(e){
                        // we don't actually catch anything, we just want to stop the error from throwing
                    }

                    return url;
                }

                function urlChecker(window, callback){
                    this.oldUrl = checkWindowUrl(window);
                    this.Check;

                    var that = this;
                    var detect = function(){
                        var currentUrl = checkWindowUrl(window);
                        if(that.oldUrl != currentUrl){
                            callback(currentUrl);
                            that.oldUrl = currentUrl;
                        }
                    };
                    this.Check = setInterval(function(){ detect() }, 100);
                }

                var ref = window.open(url);
                var hashHandler = new urlChecker(ref, function(url){
                    if (jso.URLcontainsToken(url)) {
                        // ref.removeEventListener('loadstop', onNewURLinspector);
                        ref.close();
                        var afterAuthCallback = function() {
                            // When we've found OAuth credentials, we close the inappbrowser...
                            //utils.log("Closing window ", ref);
                            if (typeof callback === 'function') callback();
                        };

                        jso.callback(url, afterAuthCallback, jso.getProviderID());                  
                    }
                });
            }

I hope it can help somebody

@camiloperezv
Copy link

It doesn't work for me. My code looks like

var jso = new JSO({
        providerId: "facebook",
        client_id: "-----",
        redirect_uri: "http://localhost:3000/user/token",
        authorization: "https://www.facebook.com/dialog/oauth"
    });
    jso.on('redirect', jso.inappbrowser({"target": "_blank"}) );    
    jso.ajax({
        url: "https://www.facebook.com/dialog/oauth",
        oauth: {
            scopes: {
              request: ['email user_about_me public_profile']
            }
        },
        dataType: 'json',
        success: function(data) {
          console.log("Response (data):", data);
        }
    });
  }

It open the InAppBrowser, I put there my credentials, in fact the endpoint in http://localhost:3000/user/token get a call with empty params, but the browser never close and I can't continue with my app.
My inappbrowser version is cordova-plugin-inappbrowser 1.1.1 "InAppBrowser"
I hope you can help me !!

:)

Thanks

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

6 participants