In an Era of Frequent Facebook Graph API Deprecations, This Is How You Manage ASP.NET Core Login
Adding Facebook login to ASP.NET Core is supposed to be really simple. Just install the Microsoft.AspNetCore.Authentication.Facebook NuGet package, call services.AddFacebook(), set the AppId and Secret, and you're done. The login screen appears, and tokens come back as expected.
But if you trust this setup blindly, one day your service may suddenly stop working. I actually got burned by this a few years ago. The reason was simple: the default Facebook Graph API version hardcoded in the NuGet package was too old. At the time it was still using v11, and once Facebook officially ended support for that version, login broke immediately.
Why do I care so much?
At POCU Academy, we rely solely on social logins. We never store passwords or unnecessary personal data like social security numbers. Storing passwords is much riskier than many people think. Even if you encrypt and protect them well, leaks always remain a possibility. Most security incident headlines you see follow the same pattern: "our service DB was hacked → user passwords leaked."
Instead, we delegate all authentication to external providers like Facebook, Google, or Naver, and only consume the authenticated result. For us, it's basically just a signed certificate saying "this person really is who they claim to be."
Concretely, after a successful Facebook login, we typically receive values like:
- Provider key: a unique key Facebook issues per user
- Access token: the token used to access the Facebook Graph API
- (optional) Email, name, or other basic profile info
That's all we need to confirm the identity. From our perspective it's far safer. We never touch "sensitive user passwords," and the responsibility lies with the external provider.
Wait, how does OAuth work again?
Facebook login is powered by the OAuth 2.0 protocol. It can be complicated, but simplified it looks like this:
- The user clicks "Login with Facebook."
- Our service redirects the user to the Facebook login page.
- The user enters their Facebook credentials and approves access.
- Facebook redirects back to our service with an Authorization Code.
- Our service exchanges that code with Facebook for an Access Token.
- With that token, we call the
/meAPI to fetch the user profile.
The key point is that our service never needs to know the user's password directly. Facebook handles all authentication, and we only trust the "token" they issue.
The NuGet package problem
Here's the catch: the Facebook Graph API version used in this process is not always the latest. The Microsoft.AspNetCore.Authentication.Facebook package hardcodes its internal endpoints. For example, it used to default to v11, and once that version hit EOL, services broke overnight.
So I just override the endpoints directly:
services.AddAuthentication()
.AddFacebook(facebookOptions =>
{
facebookOptions.AuthorizationEndpoint = Constants.AUTHORIZATION_ENDPOINT;
facebookOptions.UserInformationEndpoint = Constants.USER_INFORMATION_ENDPOINT;
facebookOptions.TokenEndpoint = Constants.TOKEN_ENDPOINT;
facebookOptions.AppId = config["Authentication:Facebook:AppId"];
facebookOptions.AppSecret = config["Authentication:Facebook:AppSecret"];
facebookOptions.AccessDeniedPath = accountAccessDeniedPath;
facebookOptions.Events.OnRemoteFailure = handleOnRemoteFailureAsync;
});
And the constants:
public static class Constants
{
public const string AUTHORIZATION_ENDPOINT = "https://www.facebook.com/v17.0/dialog/oauth";
public const string USER_INFORMATION_ENDPOINT = "https://graph.facebook.com/v17.0/me";
public const string TOKEN_ENDPOINT = "https://graph.facebook.com/v17.0/oauth/access_token";
}
Why not remove this override?
Honestly, I'd love to remove these constants someday. If the NuGet package reliably updated to the latest API versions, I wouldn't need to maintain them myself. But reality is different… even now, with v17 nearing its deprecation date, the official NuGet release hasn't been updated. The preview branch already contains the fix, but the stable release still lags behind.
So I don't trust it. At this point, maintaining my own overrides is less stressful. Luckily, Facebook emails developers before an API version reaches EOL. When that happens, I just bump the version string in my constants and run some quick tests. It's basically "manual version management," but it keeps me from waking up to a broken login system.
Conclusion
Facebook retires old versions too frequently, and Microsoft's NuGet package doesn't always keep pace. Developers get caught in between. That's why I keep overriding the endpoints and managing versions myself.
Lesson: ASP.NET Core Facebook login? Don't trust the defaults. Manage the version yourself.