尝试使用Facebook JS SDK从Facebook注销时,getLoginStatus返回状态未知

时间:2016-01-11 15:25:31

标签: facebook facebook-graph-api facebook-javascript-sdk facebook-c#-sdk

我有一个localhost网站,我使用Facebook C#SDK通过Facebook实现登录。

启动配置类

public class ExternalLoginConfig
{
    public void ConfigureAuth(IAppBuilder app)
    {
        app.UseExternalSignInCookie(DefaultAuthenticationTypes.ExternalCookie);

        var facebookAuthenticationOptions = new FacebookAuthenticationOptions()
        {
            AppId = ConfigSettings.FacebookAppId,
            AppSecret = ConfigSettings.FacebookAppSecret,
            Scope = { "email" },
            Provider = new FacebookAuthenticationProvider()
            {
                OnAuthenticated = context =>
                {
                    var accessToken = context.AccessToken;
                    var facebookClient = new FacebookClient(accessToken);

                    var result = facebookClient.Get("me", new { fields = "email,first_name,last_name" }) as JsonObject;

                    string email = null;
                    string firstName = null;
                    string lastName = null;

                    if (result != null)
                    {
                        email = result.ContainsKey("email") ? (string) result["email"] : null;
                        firstName = result.ContainsKey("first_name") ? (string) result["first_name"] : null;
                        lastName = result.ContainsKey("last_name") ? (string) result["last_name"] : null;
                    }

                    if (firstName != null)
                    {
                        context.Identity.AddClaim(new Claim(ClaimTypes.GivenName, firstName));
                    }
                    if (lastName != null)
                    {
                        context.Identity.AddClaim(new Claim(ClaimTypes.Surname, lastName));
                    }
                    if (email != null)
                    {
                        context.Identity.AddClaim(new Claim(ClaimTypes.Email, email));
                    }

                    return Task.FromResult(0);
                },
                OnApplyRedirect = context =>
                {
                    context.Response.Redirect(context.RedirectUri + "&auth_type=reauthenticate");
                }
            }
        };
        app.UseFacebookAuthentication(facebookAuthenticationOptions);
    }
}

操作形式验证控制器

[HttpPost]
[AllowAnonymous]
public virtual ActionResult Login(string provider, string returnUrl)
{
    ControllerContext.HttpContext.Session.RemoveAll();

    return new ExternalLoginResult(provider,
        Url.Action("LoginCallback", "Oauth", new { ReturnUrl = returnUrl }));
}

[AllowAnonymous]
public async Task<ActionResult> LoginCallback(string returnUrl, string error)
{
    var loginInfo = await AuthenticationManager.GetExternalLoginInfoAsync();

    if (loginInfo == null)
    {
        return Redirect(returnUrl);
    }

    User user = null;
    string userName = Guid.NewGuid().ToString();
    string firstName = loginInfo.ExternalIdentity.FindFirstValue(ClaimTypes.GivenName);
    string lastName = loginInfo.ExternalIdentity.FindFirstValue(ClaimTypes.Surname);
    string email = loginInfo.ExternalIdentity.FindFirstValue(ClaimTypes.Email);
    string externalProviderName = loginInfo.Login.LoginProvider;
    string externalProviderKey = loginInfo.Login.ProviderKey;

    var externalAuthenticationInfo = new ExternalAuthenticationInfo()
    {
        Username = userName,
        Email = email,
        FirstName = firstName,
        LastName = lastName,
        ExternalProviderName = externalProviderName,
        ExternalProviderKey = externalProviderKey
    };

    var loginResult = userProvider.ExternalLogin(externalProviderKey, email, out user);

    switch (loginResult)
    {
        case LoginResult.Success:
        {
            AuthenticationHelper.SetAuthenticatedUserId(user.ID);
            break;
        }
        case LoginResult.NotRegistered:
        {
            var registerResult = userProvider.Register(userName, email, null, externalAuthenticationInfo);

            if (registerResult.IsValid)
            {
                AuthenticationHelper.SetAuthenticatedUserId(registerResult.Result.ID);
            }

            break;
        }
    }

    return Redirect(returnUrl);
}

Facebook JS SDK初始化

window.fbAsyncInit = function () {
    FB.init({
        appId: '@ConfigSettings.FacebookAppId',
        xfbml: true,
        version: 'v2.4'
    });
};

(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/sdk.js";
    fjs.parentNode.insertBefore(js, fjs);
}(document, 'script', 'facebook-jssdk'));

我正在尝试使用Facebook JS SDK将用户从Facebook注销,但是请致电:

FB.getLoginStatus(function facebookLogoutCallback(facebookResponse) {
    if (facebookResponse.status !== 'connected') {
        return;
    }

    FB.logout(facebookLogoutCallback);
});

会导致状态unknown而不是connected,而facebookResponse会在FB.logout()对象中返回。我还尝试在没有if声明的情况下致电max-width: 640px;,但它没有用。

也许您可以说,这种行为是由未经授权的用户状态引起的,但在服务器端登录后,用户实际上已登录:在我的网站和Facebook上。

1 个答案:

答案 0 :(得分:9)

似乎FB.logout函数中存在一个错误。在调用它之后,用户无法使用JS SDK再次登录此应用程序,因为FB.login函数返回
对象{status =&#34; unknown&#34;,authResponse = null}

编辑:
发现有一个名为&#34; fblo _ *&#34;的cookie。在FB.logout()之后创建,这似乎就是这个原因。我不能确切地说出它为什么以及它的作用,但删除它会使登录再次起作用。

因此我创建了一个小脚本来查找此cookie并在我调用FB.login()之前将其删除,您可能希望在点击事件(https://developers.facebook.com/docs/reference/javascript/FB.login/v2.5)中调用它。

function delete_cookie(name) 
{
    document.cookie = name + '=; expires=Thu, 01 Jan 1970 00:00:01 GMT; path=/';
}


var cookies = document.cookie.split(";");
for (var i = 0; i < cookies.length; i++)
{
    if(cookies[i].split("=")[0].indexOf("fblo_") != -1)
        delete_cookie(cookies[i].split("=")[0]);
}