iOS 版 Chrome 中的 Facebook OAuth“不支持”

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/16843116/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-30 23:44:14  来源:igfitidea点击:

Facebook OAuth "Unsupported" in Chrome on iOS

javascriptiphoneiosfacebook

提问by Daniel Miller

The Facebook OAuth popup is throwing an error in Chrome on iOS only. Both developers.facebook.com and google have turned up nothing about this. Ideas?

Facebook OAuth 弹出窗口仅在 iOS 上的 Chrome 中引发错误。developer.facebook.com 和 google 都没有提及此事。想法?

screenshot of facebook oath popup on mobile chrome on ios

ios 上的移动 chrome 上的 facebook 誓言弹出屏幕截图

采纳答案by Kim D.

You can use the redirection method as follow for this case (by detecting the user agent being chrome ios):

对于这种情况,您可以使用如下重定向方法(通过检测用户代理为 chrome ios):

https://www.facebook.com/dialog/oauth?client_id={app-id}&redirect_uri={redirect-uri}

See more info here https://developers.facebook.com/docs/facebook-login/login-flow-for-web-no-jssdk/

在此处查看更多信息https://developers.facebook.com/docs/facebook-login/login-flow-for-web-no-jssdk/

Remark: I personnaly use the server OAuth in that case but this should do the trick and is quite simple

备注:在这种情况下,我个人使用服务器 OAuth,但这应该可以解决问题并且非常简单

回答by vsync

This is how I did it (fixing iOS chrome specifically)

我就是这样做的(专门修复 iOS chrome)

// fix iOS Chrome
if( navigator.userAgent.match('CriOS') )
    window.open('https://www.facebook.com/dialog/oauth?client_id='+appID+'&redirect_uri='+ document.location.href +'&scope=email,public_profile', '', null);
else
    FB.login(null, {scope: 'email,public_profile'});

回答by Sean

Here is a complete workaround for your FB JS Auth on Chrome iOS issuehttp://seanshadmand.com/2015/03/06/facebook-js-login-on-chrome-ios-workaround/

这是您在 Chrome iOS 问题上FB JS身份验证的完整解决方法http://seanshadmand.com/2015/03/06/facebook-js-login-on-chrome-ios-workaround/

JS functions to check auth, open FB auth page manually and refresh auth tokens on original page once complete:

JS 函数来检查身份验证,手动打开 FB 身份验证页面并在完成后刷新原始页面上的身份验证令牌:

function openFBLoginDialogManually(){
  // Open your auth window containing FB auth page 
  // with forward URL to your Opened Window handler page (below)

  var redirect_uri = "&redirect_uri=" + ABSOLUTE_URI + "fbjscomplete";
  var scope = "&scope=public_profile,email,user_friends";
  var url = "https://www.facebook.com/dialog/oauth?client_id=" + FB_ID + redirect_uri + scope;

  // notice the lack of other param in window.open
  // for some reason the opener is set to null
  // and the opened window can NOT reference it
  // if params are passed. #Chrome iOS Bug
  window.open(url);

}

function fbCompleteLogin(){

  FB.getLoginStatus(function(response) {
    // Calling this with the extra setting "true" forces
    // a non-cached request and updates the FB cache.
    // Since the auth login elsewhere validated the user
    // this update will now asyncronously mark the user as authed
  }, true);

}

function requireLogin(callback){

    FB.getLoginStatus(function(response) {
        if (response.status != "connected"){
            showLogin();
        }else{
            checkAuth(response.authResponse.accessToken, response.authResponse.userID, function(success){
              // Check FB tokens against your API to make sure user is valid
            });
        }
    });

}

And the Opener Handler that FB auth forwards to and calls a refresh to the main page. Note the window.open in Chrome iOS has bugs too so call it correctly as noted above:

以及 FB auth 转发到的 Opener Handler 并调用主页面的刷新。请注意 Chrome iOS 中的 window.open 也有错误,因此请按上述正确调用它:

<html>
<head>
<script type="text/javascript">
function handleAuth(){
    // once the window is open 
    window.opener.fbCompleteLogin();
    window.close();    
}
</script>
<body onload="handleAuth();">
    <p>. . . </p>
</body>
</head>
</html>

回答by Abhishek

This is a very common issue which all developers have faced while implementing the FB login feature. I have tried most of the Internet solutions but none of them worked. Either window.openerdo not work in Chrome iOS or sometime FB object is not loaded while using /dialog/oauth.

这是所有开发人员在实现 FB 登录功能时都面临的一个非常普遍的问题。我已经尝试了大多数 Internet 解决方案,但没有一个奏效。要么window.opener在 Chrome iOS 中不起作用,要么有时在使用/dialog/oauth.

Finally I solved this by myself after trying all the hacks!

在尝试了所有黑客之后,我终于自己解决了这个问题!

function loginWithFacebook()
{
  if( navigator.userAgent.match('CriOS') )
  {
    var redirect_uri = document.location.href;
    if(redirect_uri.indexOf('?') !== -1)
    {
      redirect_uri += '&back_from_fb=1';
    }
    else
    {
      redirect_uri += '?back_from_fb=1';
    }
    var url = 'https://www.facebook.com/dialog/oauth?client_id=[app-id]&redirect_uri='+redirect_uri+'&scope=email,public_profile';
    var win = window.open(url, '_self');
  }
  else
  {
    FB.login(function(response)
      {
        checkLoginState();
      },
      {
        scope:'public_profile,email,user_friends,user_photos'
      });
  }
}

Notice that above I'm passing an extra param to the redirect url so that once the new window opens with above redirect uri I could read the values and can say yes this call is from Chrome iOS window. Also make sure this code runs on page load.

请注意,上面我向重定向 url 传递了一个额外的参数,以便在使用上述重定向 uri 打开新窗口后,我可以读取这些值,并且可以说是这个调用来自 Chrome iOS 窗口。还要确保此代码在页面加载时运行。

if (document.URL.indexOf('back_from_fb=1') != -1 && document.URL.indexOf('code=') != -1)
{
  pollingInterval = setInterval(function()
    {
      if(typeof FB != "undefined")
      {
        FB.getLoginStatus(function(response) {}, true);
        checkLoginState();
      }
      else
      {
        alert("FB is not responding, Please try again!", function()
          {
            return true;
          });
      }
    }, 1000);
}

回答by chifliiiii

My 2 cents on this as noone of the answers were clear to me. Im firing the login js dialog on a button click, so now when it's chrome ios I check first if the user it's logged into facebook and if not I send them to the login window. The problem with this is that chome ios users needs to click connect button twice if they are not logged into facebook. If they are logged into facebook one click is enough.

我为此付出了 2 美分,因为没有一个答案对我来说是清楚的。我在单击按钮时触发登录 js 对话框,所以现在当它是 chrome ios 时,我首先检查用户是否登录到 facebook,如果没有,我将它们发送到登录窗口。这样做的问题是,如果 chome ios 用户没有登录 Facebook,他们需要单击连接按钮两次。如果他们登录到 facebook,一键就足够了。

 $( 'body' ).on( 'click', '.js-fbl', function( e ) {
        e.preventDefault();

        if( navigator.userAgent.match('CriOS') ) {
            // alert users they will need to click again, don't use alert or popup will be blocked
            $('<p class="fbl_error">MESSAGE HERE</p>').insertAfter( $(this));
            FB.getLoginStatus( handleResponse );
        } else {
            // regular users simple login
            try {
                FB.login( handleResponse , {
                    scope: fbl.scopes,
                    return_scopes: true,
                    auth_type: 'rerequest'
                });
            } catch (err) {
                $this.removeClass('fbl-loading');

            }
        }
    });

That bit of code make it works for chrome ios users. On handle response I simple take care of fb response and send it to my website backend for login/register users.

这段代码使它适用于 chrome ios 用户。在处理响应时,我简单地处理 fb 响应并将其发送到我的网站后端以供登录/注册用户使用。

var handleResponse = function( response ) {
    var $form_obj       = window.fbl_button.parents('.flp_wrapper').find('form') || false,
        $redirect_to    = $form_obj.find('input[name="redirect_to"]').val() || window.fbl_button.data('redirect');
    /**
     * If we get a successful authorization response we handle it
     */
    if (response.status == 'connected') {

        var fb_response = response;

        /**
         * Make an Ajax request to the "facebook_login" function
         * passing the params: username, fb_id and email.
         *
         * @note Not all users have user names, but all have email
         * @note Must set global to false to prevent gloabl ajax methods
         */
        $.ajax({...});

    } else {
         //if in first click user is not logged into their facebook we then show the login window
         window.fbl_button.removeClass('fbl-loading');
        if( navigator.userAgent.match('CriOS') )
            window.open('https://www.facebook.com/dialog/oauth?client_id=' + fbl.appId + '&redirect_uri=' + document.location.href + '&scope=email,public_profile', '', null);
    }
};

Hope it helps!

希望能帮助到你!

回答by akotian

Not a real answer but based on this threadworth noting that is started working for our app, on Chrome when on the iPhone we did General>Reset>Reset Location & Privacy

不是一个真正的答案,但基于这个值得注意的线程,它开始为我们的应用程序工作,当我们在 iPhone 上时,在 Chrome 上General>Reset>Reset Location & Privacy

回答by Himanshu sharma

I got a solution for ios facebook website login in google chrome . Actually the issue was with google chrome in ios when we click on facebook login button it give internally null to the window.open in ios chrome .
Thereare two solution either to check it is chrome in ios(chrios) and then generate custom login screen ( still not chance that it will we correct ).
Secondwhat i have used. Is to use facebook login from backhand create a api hit will populate facebook screen and then when login is done it will redirect to your server from where you will redirect to your website page with facebook data.
one other benefitof it is that you create 2 website for same website owner you can not set two website url in facebook developer account .In this way you can create many website facebook login with same facebook appid .

我得到了一个在 google chrome 中登录 ios facebook 网站的解决方案。实际上,问题出在 ios 中的 google chrome 上,当我们点击 facebook 登录按钮时,它在内部为 ios chrome 中的 window.open 提供了 null。
两种解决方案,要么在 ios(chrios) 中检查它是 chrome,然后生成自定义登录屏幕(仍然没有机会我们纠正它)。
其次是我用过的。是使用来自反手的 facebook 登录创建一个 api 命中将填充 facebook 屏幕,然后当登录完成后,它将重定向到您的服务器,从那里您将重定向到带有 facebook 数据的网站页面。
另一项好处其中一个原因是您为同一个网站所有者创建了 2 个网站,您不能在 facebook 开发者帐户中设置两个网站 url。这样您就可以使用相同的 facebook appid 创建多个网站 facebook 登录。