Authentication 您可以在其他FB方法(如FB.getLoginStatus)的回调中调用FB.login而不触发弹出窗口阻止程序吗?

Authentication 您可以在其他FB方法(如FB.getLoginStatus)的回调中调用FB.login而不触发弹出窗口阻止程序吗?,authentication,popup,facebook-javascript-sdk,facebook-authentication,Authentication,Popup,Facebook Javascript Sdk,Facebook Authentication,我正在尝试使用FB JavaScript SDK设置一个非常基本的身份验证逻辑流,以便在执行操作之前检查用户的登录状态和权限(如果没有权限,则提示用户使用权限登录) 用户在我的网站上的文本区域中键入一条消息以发布到他们的Facebook提要,然后单击我网站上的“发布到Facebook”按钮 作为对单击的响应,我使用FB.getLoginStatus检查用户的登录状态 在对FB.getLoginStatus的回调中,如果用户未登录,则提示他们登录(FB.login) 在对FB.login的回调中,

我正在尝试使用FB JavaScript SDK设置一个非常基本的身份验证逻辑流,以便在执行操作之前检查用户的登录状态和权限(如果没有权限,则提示用户使用权限登录)

  • 用户在我的网站上的文本区域中键入一条消息以发布到他们的Facebook提要,然后单击我网站上的“发布到Facebook”按钮
  • 作为对单击的响应,我使用
    FB.getLoginStatus
    检查用户的登录状态
  • 在对
    FB.getLoginStatus
    的回调中,如果用户未登录,则提示他们登录(
    FB.login
  • 在对
    FB.login
    的回调中,我需要确保他们拥有正确的权限,因此我调用
    FB.api('/me/permissions')
    ——如果他们没有,我会再次提示他们登录(
    FB.login
  • 我遇到的问题是,每当我试图在对其他FB方法的回调中调用
    FB.login
    ,浏览器似乎会丢失执行的来源(单击),从而阻止弹出窗口。我想知道我是否缺少一些方法来提示用户在检查他们的状态后登录,而不会让浏览器错误地认为这不是用户启动的弹出窗口

    我现在已经退回到只需先调用
    FB.login()
    。然而,这种方法不希望出现的副作用是,如果用户已使用权限登录,而我仍在调用
    FB.login
    ,则验证弹出窗口将在继续之前立即打开和关闭,尽管功能正常,但看起来还是有问题

    在做某件事之前检查用户的登录状态和权限似乎是一个常见的流程,所以我觉得我遗漏了什么。下面是一些示例代码

    <div onclick="onClickPostBtn()">Post to Facebook</div>
    
    <script>
    // Callback to click on Post button.
    function onClickPostBtn() {
    
        // Check if logged in, prompt to do so if not.
        FB.getLoginStatus(function(response) {
            if (response.status === 'connected') {
                checkPermissions(response.authResponse.accessToken);
            } else {
                FB.login(function(){}, {scope: 'publish_stream'})
            }
        });
    }
    
    // Logged in, check permissions.
    function checkPermissions(accessToken) {
        FB.api('/me/permissions',
            {'access_token': accessToken},
            function(response){
    
                // Logged in and authorized for this site.
                if (response.data && response.data.length) {
    
                    // Parse response object to check for permission here...
    
                    if (hasPermission) {
                        // Logged in with permission, perform some action.
                    } else {
                        // Logged in without proper permission, request login with permissions.
                        FB.login(function(){}, {scope: 'publish_stream'})
                    }
    
                // Logged in to FB but not authorized for this site.
                } else {
                    FB.login(function(){}, {scope: 'publish_stream'})
                }
            }
        );
    }
    </script>
    
    发布到Facebook
    //回调以单击Post按钮。
    函数onClickPostBtn(){
    //检查是否已登录,如果未登录,则提示登录。
    FB.getLoginStatus(函数(响应){
    如果(response.status===“已连接”){
    检查权限(response.authResponse.accessToken);
    }否则{
    login(函数(){},{scope:'publish_stream'})
    }
    });
    }
    //已登录,请检查权限。
    函数检查权限(accessToken){
    FB.api(“/me/permissions”,
    {'access_token':accessToken},
    功能(响应){
    //已登录并授权此站点。
    if(response.data&&response.data.length){
    //在此处分析响应对象以检查权限。。。
    如果(已获得许可){
    //使用权限登录,执行一些操作。
    }否则{
    //未经适当权限登录,请求使用权限登录。
    login(函数(){},{scope:'publish_stream'})
    }
    //已登录到FB,但未对此站点进行授权。
    }否则{
    login(函数(){},{scope:'publish_stream'})
    }
    }
    );
    }
    
    我遇到的问题是,每当我尝试在对其他FB方法的回调中调用FB.login时,浏览器似乎会忘记执行的来源(单击),因此会阻止弹出窗口

    他实际上并没有“迷失方向”——这是一个完全不同的执行上下文,因为FB方法是异步工作的。单击发生在一个执行上下文中,该上下文早就消失了,并在执行回调函数时完成

    您可以在页面加载时提前检查权限。我想,当用户在您的网站上时,其给定权限的某些内容不太可能发生变化——至少对于一个“普通”用户来说是这样,他不会试图干扰您的应用程序以查看其反应如何。(尽管在某些情况下,这一点可能无法确定。)

    如果这导致缺少必要权限的信息,则在按钮上调用FB.login,单击请求此权限。在FB.login回调中,您可以再次检查权限,如果您想确定-如果仍然没有授予权限,那么我建议提醒用户这一事实,也许再次告诉他为什么有必要这样做-然后他必须再次单击启动整个操作的按钮


    如果权限没有问题,那么您可以进行API调用以实际发布帖子。为了确保安全,在该API调用的回调中,您可以再次检查成功或错误,如果出现错误,请查明是否是由于缺少权限造成的–如果是,请回到原点,告诉用户权限是必要的,并让他重新开始整件事,通过单击按钮…

    我找到了另一种更优雅的方法来检查用户是否有

    • A) 登录FB
    • B) 正确权限
    简而言之,对于a),您需要“提醒”用户他没有登录,而不是“回调”Fb.login。然后,您的页面应该刷新,并在刷新期间处理登录过程

    但是,对于B)权限,您可以使用fb.ui方法(使用display:iframe)请求权限(通过回调),而不是使用fb.login请求权限。使用display:iframe应该可以避免弹出窗口拦截器带来的麻烦

    请参见下面修改的代码:

    <div onclick="onClickPostBtn()">Post to Facebook</div>
    
    <script>
    // Callback to click on Post button.
    function onClickPostBtn() {
    
        // Check if logged in, prompt to do so if not.
        FB.getLoginStatus(function(response) {
            if (response.status === 'connected') {
                checkPermissions(response.authResponse.accessToken);
            } else {
                //Don't call FB.login because this results in popup blocker.
                //FB.login(function(){}, {scope: 'publish_stream'})
                //Instead, just alert user that "YOu are not connected to FB", and then refresh the page (which should theoreticalyl handle the logging aspect)
            }
        });
    }
    
    // Logged in, check permissions.
    function checkPermissions(accessToken) {
        FB.api('/me/permissions',
            {'access_token': accessToken},
            function(response){
    
                // Logged in and authorized for this site.
                if (response.data && response.data.length) {
    
                    // Parse response object to check for permission here...
    
                    if (hasPermission) {
                        // Logged in with permission, perform some action.
                    } else {
                        //Don't use FB.login to request permissions. Instead use a FB.ui ({method:'permissions.request'} with "display" set to "iframe"
                        //FB.login(function(){}, {scope: 'publish_stream'})
    
                        FB.ui(
                        {
                             method: 'permissions.request',
                             'perms': 'publish_stream,WHATEVER_PERMISSIONS',
                             'display': 'iframe' //THIS IS IMPORTANT TO PREVENT POPUP BLOCKER
                        },
                        function(response) {
                            //Do action if permissions add success other wise prompt error adding permissions.
                        }
                    }
    
                // Logged in to FB but not authorized for this site.
                } else {
    
                    //Don't call FB.login because this results in popup blocker.
                    //FB.login(function(){}, {scope: 'publish_stream'})
                    //Instead, just alert user that "YOu are not connected to FB", and then refresh the page (which should theoreticalyl handle the logging aspect)
                }
            }
        );
    }
    </script>
    
    发布到Facebook
    //回调以单击Post按钮。
    函数onClickPostBtn(){
    //检查是否已登录,如果未登录,则提示登录。
    FB.getLoginStatus(函数(响应){
    如果(response.status===“已连接”){
    检查权限(response.authResponse.accessToken);
    }否则{
    //不要调用FB.login,因为这会导致弹出窗口阻止程序。