I thought I'd throw on some notes for Visual Studio 2015 templates / the latest boiler plate code for WebAPI 2. I was getting this problem with google authentication but figure its similar to facebook and the other social logins. I had the latest Owin and my other nuget packages were up-to-date. Turns out with the latest out-of-the-box web api 2 templates, I just needed to specifically request the "email" be included back from google. Without this line, the api/Account/Register call would error.
And of course make sure your app is registered with google and your site is allowed to call it. (Lots of good examples showing those steps.)
https://console.developers.google.com/apis
Here's my adjustment in the App_Start\Startup.Auth.cs file:
var googleOptions = new GoogleOAuth2AuthenticationOptions()
{
ClientId = "xxx",
ClientSecret = "xxx"
};
googleOptions.Scope.Add("email"); //!! Add this !!
app.UseGoogleAuthentication(googleOptions);
Until I added the .Add("email"), line, the api/Account/RegisterExternal WebAPI 2 call (AccountController.cs) would return null from this section of RegisterExternal:
var info = await Authentication.GetExternalLoginInfoAsync();
if (info == null) //This would be true, and it would error.
{
return InternalServerError();
}
Since this is one of the few articles that come up for this error, I figured I'd tag my notes on my solution for posterity. (especially the postman test process!)
So to make it all work in testing:
1) Call the api/Account/ExternalLogins URL like this:
http://localhost:59137/api/Account/ExternalLogins?returnUrl=%2F&generateState=true
You should get a response like this:
<ArrayOfExternalLoginViewModel xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.datacontract.org/2004/07/TCG_DL_API.Models">
<ExternalLoginViewModel>
<Name>Google</Name>
<State>1phegLF241xeSfd8gZAsCXiBAp3l5bMygg2VSeRXAHk1</State>
<Url>
/api/Account/ExternalLogin?provider=Google&response_type=token&client_id=self&redirect_uri=http%3A%2F%2Flocalhost%3A59137%2F&state=1phegLF241xeSfd8gZAsCXiBAp3l5bMygg2VSeRXAHk1
</Url>
</ExternalLoginViewModel>
</ArrayOfExternalLoginViewModel>
2) Then get the Url from the response, and call it. You should get the google login prompt/page. (Or I assume the facebook or twitter one, if that's what you set up.)
3) Login, and you'll get redirected back to your redirect page. It'll have a URL like something like this:
http://localhost:59137/#access_token=d5asC1arCUXaLEMgBS8PT_uwZcTJqC1UZbXblNZ3hMOh3TSKtEXYeKtyKBTv3WmLcaLGGomSvpRSFMfXPxpPvNRgjUVWAiqxtKfv3qWHNqfIMeu5j0eZrJDRAMTrYFgflSbEopAe909a31I4mQnJuvaiITHYPrLmqkm6J88HAVx8F981_q_tflu4A72k3KaB-m2wd0-p1jdQnNMlixM2Wfloh_niUTBIOYUPc1SkKWcZxuI6dzN2Z0PmWHDwzJI8nM8vOuzybJIsxLOyTY1VfzSQ5Qzcll3HhifLPkyZxvXDQ5LHqW1v0_AztsUWkEhW_AJzmw2IaOcTtHCmkmWm1K444okNtOsYfs6HFui0NeY&token_type=bearer&expires_in=1209600&state=3FSOd3_n_sEL4QtiELWPG5B2_H3wRjVb75uDjQS16gk1
grab the token (bold above) and use it as the bearer token.
4) Now since you aren't registered (but you do have a bearer token), you can call the POST api/Account/RegisterExternal
5) The response will be OK, and if you look in your AspnetUser tables, you'll see that you have a new AspnetUsers record and a new AspNetUserLogins record for google as the provider.
I hope this helps with anyone trying to get this stuff to work!