2017年更新!
我在发布原始问题时遇到的问题与Facebook最近在强迫每个人使用其API版本2.3时所做的更改无关.有关该特定问题的解决方案,请参阅下面的sammy34的答案./ oauth/access_token端点的2.3版现在返回JSON而不是表单编码的值
由于历史原因,这是我原来的问题/问题:
我有一个MVC5 Web应用程序,它使用内置支持通过Facebook和Google进行身份验证.几个月前我们构建这个应用程序时,我们遵循了这个教程:http://www.asp.net/mvc/tutorials/mvc-5/create-an-aspnet-mvc-5-app-with-facebook-and -google-oauth2-and-openid-sign-on,一切都很棒.
现在,突然之间,Facebook身份验证刚刚停止工作.Google身份验证仍然有效.
问题描述:我们点击链接使用Facebook连接,我们被重定向到Facebook,如果我们不允许我们的Facebook应用访问我们的个人资料,我们会被提示.当我们点击"确定"时,我们会被重定向回我们的网站,但我们只是登录屏幕而不是登录.
我已经在调试模式下完成了这个过程,并且根据上面提到的教程,我在我的帐户控制器中有了这个ActionResult:
// GET: /Account/ExternalLoginCallback
[AllowAnonymous]
public async Task<ActionResult> ExternalLoginCallback(string returnUrl)
{
var loginInfo = await AuthenticationManager.GetExternalLoginInfoAsync();
if (loginInfo == null)
{
return RedirectToAction("Login");
}
............
Run Code Online (Sandbox Code Playgroud)
当单步执行代码并从Facebook返回时,loginInfo对象始终为NULL,这会导致用户重定向回登录.
为了理解幕后实际发生的事情,我安装了Fiddler并监控HTTP流量.我发现的是,在Facebook权限对话框中单击"确定"后,Facebook会使用以下URL重定向回我们的应用程序:
https://localhost/signin-facebook?code=<access-token>
Run Code Online (Sandbox Code Playgroud)
这个URL不是一个实际的文件,可能是由我猜测的这个OWIN框架内置的一些控制器/处理程序处理的.最有可能的是,它使用给定的代码连接回Facebook,以查询有关尝试登录的用户的信息.现在,问题是我们被重定向到:而不是这样做:
/Account/ExternalLoginCallback?error=access_denied
Run Code Online (Sandbox Code Playgroud)
我确信这是Facebook正在做的事情,也就是说,它不是向我们提供用户数据,而是通过此错误消息重定向我们.
这会导致AuthenticationManager.GetExternalLoginInfoAsync();失败并始终返回NULL.
我完全没有想法.据我们所知,我们没有改变任何事情.
我已经尝试创建一个新的Facebook应用程序,我已经尝试过再次使用该教程,但我总是遇到同样的问题.
欢迎任何想法!
更新!
好的,这让我疯了!我现在已经手动完成了执行身份验证所需的步骤,当我这样做时,一切都很顺利.为什么在使用MVC5 Owin的东西时这不起作用?
这就是我做的:
// Step 1 - Pasted this into a browser, this returns a code
https://www.facebook.com/dialog/oauth?response_type=code&client_id=619359858118523&redirect_uri=https%3A%2F%2Flocalhost%2Fsignin-facebook&scope=&state=u9R1m4iRI6Td4yACEgO99ETQw9NAos06bZWilJxJrXRn1rh4KEQhfuEVAq52UPnUif-lEHgayyWrsrdlW6t3ghLD8iFGX5S2iUBHotyTqCCQ9lx2Nl091pHPIw1N0JV23sc4wYfOs2YU5smyw9MGhcEuinvTAEql2QhBowR62FfU6PY4lA6m8pD3odI5MwBYOMor3eMLu2qnpEk0GekbtTVWgQnKnH6t1UcC6KcNXYY
I was redirected back to localhost (which I had shut …Run Code Online (Sandbox Code Playgroud) 显然,您可以通过在以下FacebookAuthenticationOptions对象中添加范围来向Facebook提供商执行此操作Startup.Auth.cs:
List<string> scope = new List<string>() { "email" };
var x = new FacebookAuthenticationOptions();
x.Scope.Add("email");
...
app.UseFacebookAuthentication(x);
Run Code Online (Sandbox Code Playgroud)
如何与Google提供商进行相同的操作?类/对象没有x.Scope属性GoogleAuthenticationOptions!
使用Facebook API的v2.3,如果设置了以下内容,则会在回调时返回用户的电子邮件地址ExternalLoginCallback;
app.UseFacebookAuthentication(new FacebookAuthenticationOptions
{
AppId = "XXX",
AppSecret = "XXX",
Scope = { "email" }
});
Run Code Online (Sandbox Code Playgroud)
但是,任何只能针对v2.4(7月8日发布)的应用程序不再将电子邮件地址返回给ExternalLoginCallback.
我认为这可能与此处列出的v2.4更改有关;
声明字段
要尝试提高移动网络的性能,v2.4中的节点和边缘要求您明确请求GET请求所需的字段.例如,
GET /v2.4/me/feed默认情况下不再包含喜欢和评论,但GET /v2.4/me/feed?fields=comments,likes会返回数据.有关更多详细信息,请参阅有关如何请求特定字段的文档.
我现在如何访问此电子邮件地址?
我使用默认的Visual Studio 2015模板和Google身份验证开发了ASPNET MVC 5应用程序.一切都在开发环境中正常工作,但实际上外部认证后的调用AuthenticationManager.GetExternalLoginInfoAsync()有时会返回null.
通常它在当天的中央时间(从08:00到20:00)返回null,但我没有找到模式,因为有时候工作.我看过开发者控制台,但是没有很多请求(过去12小时内有22个)并且都是成功的.
我尝试过其他StackOverflow线程的一些解决方案,但它们不起作用.此外,我只能在晚上尝试它们,因为这是一个个人项目,然后连接成功,我无法重现这个问题.
代码是标准的:
在启动时
public void ConfigureAuth(IAppBuilder app)
{
// Configure the db context, user manager and signin manager to use a single instance per request
app.CreatePerOwinContext(ApplicationDbContext.Create);
app.CreatePerOwinContext<ApplicationUserManager>(ApplicationUserManager.Create);
app.CreatePerOwinContext<ApplicationSignInManager>(ApplicationSignInManager.Create);
// Enable the application to use a cookie to store information for the signed in user
// and to use a cookie to temporarily store information about a user logging in with a third party login provider
// Configure the sign in cookie
app.UseCookieAuthentication(new …Run Code Online (Sandbox Code Playgroud)我正在学习如何使用VS 2015中的默认MVC模板使用OWIN外部auth.我启用了Facebook auth并添加了范围"email",期望在用户通过身份验证后由Facebook返回用户的电子邮件(根据此) .但是,上下文中没有电子邮件.用户JSON对象和context.Email也为空.
这是Startup.Auth.cs中的相关代码
var facebookOptions = new FacebookAuthenticationOptions
{
AppId = "XXXXXX",
AppSecret = "XXXXXX",
Provider = new FacebookAuthenticationProvider
{
OnAuthenticated = context =>
{
// Retrieve the OAuth access token to store for subsequent API calls
var accessToken = context.AccessToken;
// Retrieve the username
var facebookUserName = context.UserName;
// WHY IS IT EMPTY?
var facebookEmail = context.Email;
// You can even retrieve the full JSON-serialized user
var serializedUser = context.User;
return Task.FromResult(0);
}
}
}; …Run Code Online (Sandbox Code Playgroud) asp.net-mvc facebook-graph-api owin asp.net-mvc-5 asp.net-identity
我们的Facebook登录目前无效.我们收到了Facebook Developer Portal的消息:
"应用程序名称"目前可以访问Graph API v2.2,该版本将于2017年3月27日达到其2年生命周期的终点.为确保平稳过渡,请将所有调用迁移到Graph API v2.3或更高版本.
要检查您的应用是否会受到此升级的影响,您可以使用版本升级工具.这将显示哪些呼叫(如果有)受此更改影响以及更新版本中的任何替换呼叫.如果您没有看到任何电话,则您的应用可能不会受到此更改的影响.
您还可以使用我们的更改日志查看所有Graph API版本中的完整更改列表.
我们正在使用ASP.NET MVC 5,我们正在使用或认证如下:
var facebookAuthenticationOptions = new FacebookAuthenticationOptions()
{
AppId = "****",
AppSecret = "****",
AuthenticationType = "Facebook",
SignInAsAuthenticationType = "ExternalCookie",
Provider = new FacebookAuthenticationProvider
{
OnAuthenticated = async ctx => ctx.Identity.AddClaim(new Claim(ClaimTypes.Email, ctx.User["email"].ToString()))
}
};
facebookAuthenticationOptions.Scope.Add("email");
Run Code Online (Sandbox Code Playgroud)
但今天,我们的登录信息对象在ExternalLoginCallback中为null:
[HttpGet]
[AllowAnonymous]
[RequireHttps]
public async Task<ActionResult> ExternalLoginCallback(string returnUrl = null)
{
try
{
var loginInfo = await AuthenticationManager.GetExternalLoginInfoAsync();
if (loginInfo == null)
{
return RedirectToAction("Login");
}
... more code here...
Run Code Online (Sandbox Code Playgroud)
在Facebook开发.Portal我们的API版本是2.3 …
我想知道如何为Facebook外部登录添加更多权限,特别是电子邮件.外部登录工作正常,但我似乎无法将用于MVC 5的相同代码复制到这个中,所以这就是我现在所拥有的:
services.Configure<FacebookAuthenticationOptions>(options =>
{
options.AppId = Configuration["Authentication:Facebook:AppId"];
options.AppSecret = Configuration["Authentication:Facebook:AppSecret"];
options.Scope.Add("email");
});
Run Code Online (Sandbox Code Playgroud)
但它不会添加电子邮件权限.
这是我在MVC 5中使用的代码以及Facebook SDK nugget:
app.UseFacebookAuthentication(new FacebookAuthenticationOptions
{
AppId = "XXXXXX",
AppSecret = "XXXXXXX",
Scope = { "email" },
Provider = new FacebookAuthenticationProvider
{
OnAuthenticated = async context =>
{
context.Identity.AddClaim(new System.Security.Claims.Claim("FacebookAccessToken", context.AccessToken));
}
}
});
Run Code Online (Sandbox Code Playgroud)