Facebook OAuth stopped working suddenly

2019-04-20 09:27发布

问题:

I noticed yesterday that my Facebook login for my website has stopped working.

This has been working great for the last 2 months, as far as I am aware I have not changed anything. I have tried everything I can on links such as: - as well as many more...

ASP.NET MVC5 OWIN Facebook authentication suddenly not working

I have noticed that the Stack Overflow Facebook auth has also stopped working.

Has anyone else noticed this and found any solution? It's worth noting I am using azure app services to host. But this issue is also found when I am using localhost.

My current setup looks like this...

in Startup.Auth.cs

var facebookOptions = new Microsoft.Owin.Security.Facebook.FacebookAuthenticationOptions()
{
    AppId = "xxxxxxxxxxxxx",
    AppSecret = "xxxxxxxxxxxx"
};
facebookOptions.Scope.Add("email");
app.UseFacebookAuthentication(facebookOptions);

In the following method, loginInfo is null every time.

[AllowAnonymous]
public async Task<ActionResult> ExternalLoginCallback(string returnUrl)
{
    var loginInfo = await AuthenticationManager.GetExternalLoginInfoAsync();
    if (loginInfo == null)
    {
        return RedirectToAction("Login");
    }

I also added a session "WAKEUP" from a different post suggestion, fb auth failed once before and this fixed the issue this time, but it has come back.

[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public ActionResult ExternalLogin(string provider, string returnUrl)
{
    Session["WAKEUP"] = "NOW!";

    // Request a redirect to the external login provider
    return new ChallengeResult(provider, Url.Action("ExternalLoginCallback", "Account", new { ReturnUrl = returnUrl }));
}

回答1:

As RockSheep explained. Facebook dropped the support vor API v2.2. You need to update your OWIN nuget packages.

You can find the issue on github (from the Katanaproject).

Ensure to activate pre releases in your nuget manager, than you are able to update the nuget packages to version v3.1.0-rc1. But beware: After the update, you need to test your login carefully (maybe you also have other authentication providers like Microsoft or Google, you should test them as well).

Technical

The Api changed the version number to v2.8 and the return value from the API is now in JSON-Format and no longer escaped in the URI. The 'old' OWIN packages can not handle this changes.

[Oauth Access Token] Format - The response format of https://www.facebook.com/v2.3/oauth/access_token returned when you exchange a code for an access_token now return valid JSON instead of being URL encoded. The new format of this response is {"access_token": {TOKEN}, "token_type":{TYPE}, "expires_in":{TIME}}. We made this update to be compliant with section 5.1 of RFC 6749.

Here you can find the code-changes on GitHub for further informations and better understanding.



回答2:

A lot of people started having trouble after yesterday. This is due to Facebook dropping support for v2.2 of their API. For some reason their system still redirects auth calls that don't use a version number to the 2.2 API. A quickfix is to ensure that the API version gets sent with the API call.

Starting at v2.3 Facebook also started returning JSON objects. So make sure to change that in the code as well.



回答3:

I had the same issue, found solution here Fix facebook oauth 2017

Basically, you need to extend HttpClientHandler and decode JSON response instead of body



回答4:

Here is a solution for those who are using scribe java.

 public Token extract(String response)
  {
    Preconditions.checkEmptyString(response, "Response body is incorrect. Can't extract a token from an empty string");
    JSONObject obj = new JSONObject(response);
    return new Token(obj.get("access_token").toString(), EMPTY_SECRET, response);
  }


回答5:

Create a new class and set the extractor to JSON.

import org.scribe.builder.api.DefaultApi20;
import org.scribe.extractors.AccessTokenExtractor;
import org.scribe.extractors.JsonTokenExtractor;
import org.scribe.model.OAuthConfig;

public class FaceFmApi extends DefaultApi20 {

    @Override
    public String getAccessTokenEndpoint()
    {
        return "https://graph.facebook.com/oauth/access_token";
    }

    @Override
    public AccessTokenExtractor getAccessTokenExtractor()
    {
        return new JsonTokenExtractor();
    }

    @Override
    public String getAuthorizationUrl(OAuthConfig config) {
        return null;
    }
}

and inject your newly created class as below. Then getAccessToken() will work as expected.

public OAuthService getService() {
    return new ServiceBuilder().provider(FaceFmApi.class)
        .apiKey(config.getApiKey()).apiSecret(config.getApiSecret())
        .callback(config.getCallback()).build();
}