简体   繁体   中英

iOS web/native app Facebook Login Popup - FAILS?

I am trying to build a web app that will allow a user to login Facebook. Everything works in Firefox/Chrome/Safari (on the phone/tablet and on OSX).

When the App runs on the tablet (Native UIWebview and Web-app) it loads the first page perfectly.

When the user clicks the "connect with Facebook" button the app loads the Facebook logon page.

After the user logs in (again, in both a Native UIWebview and a web-app) the view turns white hanging on the URL: 'https://www.facebook.com/dialog/permissions.request?_path=permissions.request&app_id=[APP_ID]...' - this seems like it should not happen...

If I restart the app/web-app the user is logged in automatically, and redirected to the success page.

What I think is causing the problem

When you run the web page in the Firefox/Chrome/Safari browsers the Facebook login Dialog pops up as a popup or another tab (the latter on the native Safari browser).

I believe that this is a problem with this popup page and how the Javascript communicates with itself when a successful login takes place. Something with window.close where there is no root page to return to (as the web-app and UIWebview only have one instance of the webview)... maybe?

Failed work-around (UIWebview)

Since the app was hanging up on the previously mentioned URL I decided to add an if statement in shouldStartLoadWithRequest(...) to force the UIWebview to go to the success URL.

It loads the URL, but then before Facebook's Javascript SDK function FB.getLoginStatus function returns 'Connected' (It does return 'Connected' every time I've seen) The function FB.Event.subscribe('auth.logout' function() {...}); is fired.

I don't understand why it is logging the user out, then telling me that the user is connected (logged in) - in that order.

Any Ideas before I embark on trying to build this 100% native (and have to put up with apple's dev account and submitting the app)?

Login Script

<script>(function(d, s, id) {
            var js, fjs = d.getElementsByTagName(s)[0];
            if (d.getElementById(id)) return;
            js = d.createElement(s); js.id = id;
            js.src = "//connect.facebook.net/en_US/all.js#xfbml=1&appId=APP_ID";
            fjs.parentNode.insertBefore(js, fjs);
        }(document, 'script', 'facebook-jssdk'));</script>

        <script>
        var seccond_page = false;
        window.fbAsyncInit = function() {
            FB.init({
                appId      : '[APP_ID]',
                status     : true,
                cookie     : true,
                xfbml      : true,
                oauth      : true
            });

            FB.Event.subscribe('auth.login', function(response) {
                window.location.href = '<?= $success ?>';
            });

            FB.Event.subscribe('auth.logout', function(response) {
                window.location.reload();
            });

            FB.login(function(response) {
                alert(response.status);
                if (response.status) {
                    if (response.status == 'connected') {
                        window.location.href = '<?= $success ?>';
                    }
                }
            }, {scope: 'email, user_likes, user_status, user_birthday, user_location, publish_checkins'});

            $(document).on('click', '#fb_login_button', function() {
                FB.login();
            });
        };
        </script>

Success Page

    <script>
        var fb_user_id = '';
        var fb_access_token = '';
        var user_location = '';
        window.fbAsyncInit = function() {
            FB.init({
                appId      : '[APP_ID]',
                status     : true,
                cookie     : true,
                xfbml      : true,
                oauth      : true
            });

            FB.getLoginStatus(function(response) {
                alert('Response - ' + response.status); 
                // the auth.logout is fired before the return of this in the failed fix
                if (response.status === 'connected') {
                    if (response.authResponse) {
                        fb_user_id = response.authResponse.userID
                        fb_access_token = response.authResponse.accessToken;
                    }
                }

            });

            FB.Event.subscribe('auth.logout', function(response) {
                alert('logout - auth.logout'); 
                // This event is fired before the above function in the failed fix
                window.location.href = '<?= site_url('fb_login'); ?>';
            });

            FB.Event.subscribe('edge.create', function(response){
                if (response == '<?= $like_url ?>') {
                    //action
                }
            });
        };
</script>

All pages have the meta tag: <meta name="apple-mobile-web-app-capable" content="yes">

Facebook calls auth.logout just before auth.login for reasons not clear to me. You should inspect the response parameter before assuming that the user really has been logged out. Facebook docs state:

auth.logout - fired when the user logs out. The response object passed into the callback function looks like: { status: "", /* Current status of the session */ }

If you execute your logout handling only if response.status is really "" , you may find that during login, it calls auth.login listeners immediately after calling the auth.logout listener. Your current auth.logout handling prevents you from noticing this, because the page reload stops JS and ajax executions.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM