iOS 网页/原生应用 Facebook 登录弹窗 - 失败?

7

我正在尝试构建一个web应用程序,允许用户登录Facebook。在Firefox/Chrome/Safari(在手机/平板电脑和OSX上)中一切正常。

当应用程序在平板电脑上运行(本机UIWebview和Web应用程序),它完美地加载第一页。

当用户点击“使用Facebook连接”按钮时,该应用程序会加载Facebook登录页面。

用户登录后(再次在本机UIWebview和Web应用程序中),视图变为白色,挂在URL上:“https://www.facebook.com/dialog/permissions.request?_path=permissions.request&app_id=[APP_ID]...” - 这似乎不应该发生......

如果我重新启动应用程序/ Web应用程序,则用户会自动登录并重定向到成功页面。

我认为导致问题的原因

当您在Firefox / Chrome / Safari浏览器中运行网页时,Facebook登录对话框会弹出为弹出窗口或另一个选项卡(本机Safari浏览器上的后者)。

我认为这是弹出页面的问题以及成功登录时Javascript如何相互通信的问题。某些内容与window.close 有关,其中没有根页面可以返回(因为Web应用程序和UIWebview仅具有Webview的一个实例)......也许?

失败的解决方法(UIWebview)

由于应用程序挂在先前提到的URL上,我决定在 shouldStartLoadWithRequest(...)中添加if语句,以强制UIWebview转到成功的URL。

它加载了URL,但是在Facebook的Javascript SDK函数 FB.getLoginStatus 函数返回“已连接”之前(每次我看到它都会返回“已连接”),函数 FB.Event.subscribe('auth.logout' function() {...});被触发。

我不明白为什么它要注销用户,然后告诉我用户已连接(已登录) - 按照那个顺序。

在我开始尝试完全构建此应用程序之前有任何想法吗?(并且必须忍受苹果的开发帐户和提交应用程序)

登录脚本

<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>

所有页面都有元标记:<meta name="apple-mobile-web-app-capable" content="yes">,这表示网站可以在移动设备上作为应用程序运行。

3
请展示你的Facebook初始化和登录代码。 - Maksim
这是因为Facebook OAuth在选项卡窗口中进行,正如您所说,因此在像UINativeWebView这样的单个窗口浏览器窗口上失败了。 - Shireesh Asthana
当你说“原生UIWebview和Web应用程序”时,你是指设备上特定的内置或商店应用程序,还是指自定义制作的内容?另外,当你说平板电脑时,你是指iPad吗? - Spathi Wankenstein
1个回答

0

Facebook在auth.login之前调用auth.logout,原因不明确。在假定用户已经注销之前,您应该检查响应参数。Facebook文档中指出:

auth.logout - 当用户注销时触发。传递到回调函数的响应对象如下: { status: "", /* 会话的当前状态 */ }

如果您只在response.status真正为""时执行注销处理,您可能会发现在登录期间,它会在调用auth.logout监听器后立即调用auth.login监听器。由于页面重新加载停止了JS和ajax执行,因此您当前的auth.logout处理会阻止您注意到这一点。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接