问题
I have a localhost website, where I've implemented login via Facebook using Facebook C# SDK.
Startup configuration class:
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);
}
}
Actions form Authentication controller:
[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 initialization:
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'));
I'm attempting to log a user out of facebook with the Facebook JS SDK, however calling:
FB.getLoginStatus(function facebookLogoutCallback(facebookResponse) {
if (facebookResponse.status !== 'connected') {
return;
}
FB.logout(facebookLogoutCallback);
});
leads to status unknown
instead of connected
, which is returned in facebookResponse
object. I've also tried to call FB.logout()
without if
statement, but it didn't work.
Maybe you can say, that this behavior is caused by unauthorized user status, but after server side login the user is actually logged in: on my website and Facebook too.
回答1:
It seems that there's a bug currently in the FB.logout function. After calling it the user can not be logged into this App again using the JS SDK because the FB.login function returns
Object { status="unknown", authResponse=null}
EDIT:
Found that there's a cookie called "fblo_*" created after FB.logout() which seems to be the reason for this. I can't say exactly why it's there and what it does, but deleting it makes the login work again.
Therefor I created a small script that looks for this cookie and deletes it just before I call FB.login() which you probably want to call in a click event (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]);
}
来源:https://stackoverflow.com/questions/34725123/getloginstatus-returns-status-unknown-when-trying-to-logout-from-facebook-using